Cannot trigger an exception within an lambda expression - java

I am somewhat new to Java 8 and am trying to throw a an exception within an lambda expression as following: if subQty is less than min or greater than max, in this case, my unit test calculated min/max to be 182 and 255, and I am submitting a subQty of 10, therefore it should raise an exception and fail this unit test. However, I am keep getting the green light why is that?
public void verifyingIndividualSubmissionValueLimits(String alias, double min, double max)
// ... some code here ...
// Get local stock price
CompletableFuture<Double> localPriceFuture = instrumentRequester.getMidPrice(instId);
// Calculate the min and max quantity
localPriceFuture.thenAcceptBoth(dollarFxRateFuture,
(localPrice, fxRate) -> {
double minLocalValue = min * fxRate;
double maxLocalValue = max * fxRate;
long minQuantity = Math.round(minLocalValue / localPrice);
long maxQuantity = Math.round(maxLocalValue / localPrice);
if (subQty < minQuantity || subQty > maxQuantity) {
log.debug("We should throw an exception because subQty is {}", subQty);
throw new SubmissionValidationException(String.format("Quantity: %s, is not within %s and %s", subQty, minQuantity, maxQuantity));
}
}
);
}

You throws exception in different thread. You are creating a thread that calculate min, max rate and throws an exception but exception occurs in thread so you can not see any exception in main thread (in this case verifyingIndividualSubmissionValueLimits). You can read callback and async threads here https://www.callicoder.com/java-8-completablefuture-tutorial/

You can only throw exception from inside the lambda only if the #FunctionInterface it represent is throwing exception, Otherwise you will have to handle it inside the lambda only, for example this can be achieved creating your own FunctionalInterface -
public class Test {
public void foo(Fun f) throws Exception {
f.apply();
}
#FunctionalInterface
private interface Fun{
void apply() throws Exception;
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.foo(() -> {
throw new Exception();
});
}
}
In your case you are using CompletableFuture thenAcceptBoth function which use BiConsumer function interface which does not throw any exception, so it's not possible to throw it from there.
#FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
....
}
These are compile time restrictions and valid even if it's not in a separate thread.

Related

Unable to clone thread - Why?

To my understanding, Following code should generate 4 clones of the local ProcessingThread running, producing an output:
processing 0
processing 1
processing 2
processing 3
However when I try to run this program I am getting :
java.lang.CloneNotSupportedException
public class Test {
public static void main(String[] args) {
Test o = new Test();
try {
o.process(o.new ProcessingThread() {
public void run() {
System.err.println("processing " + index);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void process(ProcessingThread template) throws CloneNotSupportedException {
// Try run 4 parallel processing threads from the supplied template...
for (int i = 0; i < 4; i++) {
ProcessingThread thread = (ProcessingThread) template.clone();
thread.setIndex(i);
thread.start();
}
// ...
}
public class ProcessingThread extends Thread implements Cloneable {
int index;
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void setIndex(int i) {
index = i;
}
}
}
Please help me understand this ? and also how to rectify this problem
Just look into the source code of Thread class:
/**
* Throws CloneNotSupportedException as a Thread can not be meaningfully
* cloned. Construct a new Thread instead.
*
* #throws CloneNotSupportedException
* always
*/
#Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
Cloning thread just doesn't make sense.
Thread is not cloneable. Calling super.clone() ends up throwing CloneNotSupportedException because of this.
Threads can't be cloned because, well, that would be a really bad idea. What if the thread was already running, and had grabbed a condition variable... should both the original thread and the clone have a lock on the same variable?
It seems like what you're trying to do is create multiple instances of a worker thread subprogram. An easy way to do this if the underlying subprogram doesn't have any per-instance mutable state is to pass in a Runnable instead, and create (multiple) threads from that. Really, though, depending on your precise use case you might get more mileage out of something like ExecutorService, which may be very similar to what you're trying to (re)implement.
According to the documentation, the Thread class always throws that exception when calling clone. Since you are just calling the Thread's clone method instead of implementing your own, it's always going to throw that exception.
See:
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#clone()
Instead of using clone() you want to use a Function, or in this case, a lambda to create your tasks.
public class Test {
public static void main(String[] args) {
Test o = new Test();
o.process(ProcessingThread::new);
}
public void process(TaskBuilder template) {
// Try run 4 parallel processing threads from the supplied template...
for (int i = 0; i < 4; i++) {
new Thread(template.build(this, i)).start();
}
// ...
}
interface TaskBuilder {
Runnable build(Test t, int index);
}
static class ProcessingThread implements Runnable {
final int index;
private final Test test;
public ProcessingThread(Test test, int index) {
this.test = test;
this.index = index;
}
#Override
public void run() {
System.out.println(test + " processing " + index);
}
}
}
However, a simpler way of having N tasks in different using a template is to use a parallel stream.
public static void main(String[] args) {
IntStream.range(0, 4).parallel()
.forEach(index -> System.out.println("processing " + index));
}
prints
processing 2
processing 3
processing 0
processing 1
as there is no guarantee as to the order the tasks are processed.

How to throw a checked exception within CompletableFuture?

I used a static method supplyAsync() to get a CompletableFuture, and call its whenComplete() method to deal with the result and exception.
whenComplete() accepts a BiConsumer as parameter, and BiConsumer's second parameter is a Throwable. But I found that I can't throw a checked exception in supply() method. If I did, Idea will show a tip “Unhandled exception: java.lang.exception”.
public static void main(String[] args) {
Integer i = 0;
// unhandled exception
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> CompletableTest.getInt(i), executorService);
future.whenComplete((res, e) ->
{
System.out.println("res is " + res);
System.out.println("e is " + e);
});
}
public static Integer getInt(Integer i) throws Exception {
Thread.sleep(3000);
return i + 1;
}
I'm confused, whenComplete() can deal with checked exception, but I can't throw it.
Is it possible to throw a checked exception within CompletableFuture?

Catching an ArithmeticException but not handling as intended

I am kinda new with the whole catching-handling exceptions concept and I was wondering why the throws ArithmeticException doesn't produce an exception error message (in this case/by zero) on exit, but instead during compilation.
Shouldn't it compile normally and then show the error message at the screen? What am I doing wrong?
public class Exception_Tester
{
public static void main(String args[])
{
Exception_Tester et = new Exception_Tester();
int x1;
int x2;
x1 = 5;
x2 = 0;
et.printResults(x1, x2);
}
void printResults(int a, int b) throws ArithmeticException
{
System.out.println("Add: "+(a+b));
System.out.println("Sub: "+(a-b));
System.out.println("Mul: "+(a*b));
System.out.println("Div: "+(a/b));
}
}
I executed your code as it is
public class Exception_Tester
{
public static void main(String args[])
{
Exception_Tester et = new Exception_Tester();
int x1;
int x2;
x1 = 5;
x2 = 0;
et.printResults(x1, x2);
}
void printResults(int a, int b) throws ArithmeticException
{
System.out.println("Add: "+(a+b));
System.out.println("Sub: "+(a-b));
System.out.println("Mul: "+(a*b));
System.out.println("Div: "+(a/b));
}
}
And it compiles fine without any error or exception, and as per your requirement, it is throwing ArithmeticException at run time only when System.out.println("Div: "+(a/b)); statement is encountered.
So I don't See any Problem there!
Checked Exception : these exception will throw error while compilation if you have not handled these exceptions.
Unchecked Exception : you will get error only at RunTime if you have not handled.
ArithmaticException is unchecked exception so you will get exception at runtime.
if you are using try-catch block then you have to use
printStackTrace()
method to print exception stack trace.
as :
try{
System.out.println("Add: "+(a+b));
System.out.println("Sub: "+(a-b));
System.out.println("Mul: "+(a*b));
System.out.println("Div: "+(a/b));
}
catch(ArithmeticException e){
e.printStackTrace();
}
Take a look at the following picture:
As you can see a few of the exception classes are in a bold font to draw our attention to them. Here is the editors explanations about these categories of exceptions
Conditions that can readily occur in a correct program are checked exceptions. Concretely these kind of exceptions are <> by the compiler and he can correctly assess the eventuality of their occurence and declare a compilation error when the circumstances correspond to it. As you can see from the picture, NullPointerException is not directly under this category: these are the exception that directly extends the Exception class.
Severe problems that normally are treated as fatal or situations that probably reflect program bugs are unchecked exceptions.
Fatal situations are represented by the Error class.
Probable bugs are represented by the RuntimeException class. This is the case for exemple with the exceptions that extends the RuntimeException class. NullPointerException is one of them. In most of the cases of this kind of exception the compiler is not able to assess #compile time that they will cause an exception, since there is a strong dependency to the dynamic state of the application
Here is a simple illustration:
I have created two exceptions classes one that extends Exception
public class Exception1 extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
}
and one that extends RuntimeException
public class Exception2 extends RuntimeException {
private static final long serialVersionUID = 4595191052237661216L;
}
Then I have the following NewTester class
public class NewTester {
public static void methodA() throws Exception1 {
throw new Exception1();
}
public static void methodB() throws Exception2 {
throw new Exception2();
}
public static void main(String[] args) {
// methodA();
methodB();
}
}
I have purposefully commented the call to methodA.In this state you don't have any compilation error because the method that is called methodBthrows a RuntimeException which is unchecked. But if you would change this code by uncommenting the call to methodA and commenting the call to methodB you will have a compilation error, because methodA throws a checked exception
I hope this helps

How to change the return message of Exception.getMessage()?

I need to change the return message of the method getMessage() ,
for instance, i have an ArithmeticException, and when i write:
try{c=a/0;}
catch(ArithmeticException excep){System.out.println( excep.getMessage() );}
and I execut this code I have: / by zero.
So, I wanted to change this result by overwriting the getMesage method.
I have created a new class called MyException that inherits from ArithmeticExceprtion and I override the methode getMessage, and after that I have changed the type of the exception in my last code from ArithmeticException to my new name class MyException:
public class MyException extends ArithmeticException{
#override
public String getMessage(){
retun "new code message";}
}
and I have changed the first code, I have wrotten:
try{c=a/0;}
catch(MyException excep){System.out.println( excep.getMessage() );}
and when I have executed this code, I had the same error's message as if I didn't catch the exception:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at main.test.main(Test.java:33)
So, my question is: how can I change the message of the methode getMessage() ?
c=a/0 always throws a ArithmeticException because it's implemented this way.
If you write you're own division function that throws your MyException when dividing by 0 then you can actually catch it:
float division(float a, float b) {
if(b == 0)
throw new MyException();
return a/b;
}
...
try {
c = division(a, b);
} catch(MyException e) {
System.out.println(e.getMessage());
}
If you are using your own defined exception, you have to throw it manually like
throw new MyException();
otherwise it will throw the instance of the class ArithmeticException, so its own getMessage() function will be triggered.

Trouble with a thread-safe queue class. Specifically, with exceptions

I am using a thread-safe queue class and have a problem with the insert method I've defined. A Buffer stores an array (elementData) that uses the start/end variables to know where to add/delete stuff from the queue. It's thread-safe, so it uses synchronized methods so I can have multiple threads refer to the same buffer.
public class Buffer<T> {
private T[] elementData;
private int elementCount;
private int start;
private int end;
// Additional fields
// Code to instantiate a Buffer, other methods (e.g. delete)
public synchronized void insert(T t) throws InterruptedException {
while (elementCount == elementData.length) {
wait();
}
end = (end + 1) % elementData.length;
elementData[end] = t;
elementCount++;
notifyAll();
}
public static void main(String[] args) {
Buffer<Integer> b = new Buffer();
b.insert(3);
}
}
Here's my understanding of the situation. When a method such as insert is called, we want to be able to throw an exception that could happen when the main method or some other thread gets called and tries to perform insert while it's suspended. But what I don't understand is why I get this unreported exception. I thought that having a "throws InterruptedException" after the method would be sufficient. Do I need a "try" block? My attempts with try blocks have all failed, so I'm a little stumped as to how to fix this error.
Also, I'm aware that I don't have any actual threads running. I'll do those once I can fix this unreported exception. :) Thanks to anyone who can help.
Buffer.java:56: unreported exception java.lang.InterruptedException; must be caught or declared to be thrown
b.insert(3);
The compile exception is because your insert method could throw an InterruptedException (even if you're not throwing it on purpose), so every method that calls it must use a try/catch block, even if the error never arises:
public static void main(String[] args) {
Buffer<Integer> b = new Buffer();
try {
b.insert(3);
} catch(InterruptedException ie) {
//error handling
e.printStackTrace();
}
}

Categories