Flux getting stuck in case of any java.lang.Error(OOM) - java

In flux whenever there is OOM the whole process is getting stuck until we kill it manually. I have created an example to simulate it. Please refer the following code:
#Test
public void test_Flux() {
Flux.range(1, 30)
.parallel(6)
.runOn(Schedulers.fromExecutor(Executors.newFixedThreadPool(6)))
.doOnNext(this::writeValues)
.sequential()
.blockLast();
}
private void writeValues(int val) {
if (val == 10) {
throw new OutOfMemoryError("failed here");
// throw new RuntimeException("failed here");
}
System.out.println("the thread name is :" + Thread.currentThread().getName() + " val is :" + val);
sleep(3);
}
private void sleep(int i) {
try {
Thread.sleep(i * 1000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
Can we crash here instead of getting stuck?

Related

This method throws two different exceptions. How could man catch the two exceptions and prints exception catched for both exception types to console?

public class CatchingExceptions {
private int erroneousMethod(int p) {
if (p == 0) {
throw new IllegalArgumentException();
}
int x = 0x01;
return p / (x >> Math.abs(p)); // this line will throw!
}
The task is to implement the following method to catch and print the two exceptions.
public void catchExceptions(int passthrough) {
erroneousMethod(passthrough); // will throw!
try{
????
} catch (IllegalArgumentException e){
System.out.println("???? ");
}
}
Call the method inside the try block:
public void catchExceptions(int passthrough) {
try{
erroneousMethod(passthrough);
} catch (RuntimeException e) { // catches all unchecked exceptions
String message = e.getMessage() == null ? "" : (": " + e.getMessage());
System.out.println(e.getClass().getSimpleName() + ": " + message);
}
}

Execution order of callables is not consistent

I have this code where I execute sets of callables, I need one set to finish all it's work before triggering the next set. This code seems to work fine but sometimes next set would start running before time. What is wrong here?
private void executeSubGraph(QuestExecutionContext ctx, Set<Activity> subGraph, int progressAfterRan) {
ExecutorService pool = Executors.newFixedThreadPool(16);
subGraph.forEach(a -> {
ActivityRunner<? extends Activity> runner = activityRunnerFactory.getRunner(ctx, a);
if (runner != null) {
Callable<List<PortValuePart>> runnerCallable = () -> {
try {
LOG.info("Running {} in {}", a, a.getClass() );
List<PortValuePart> result = runner.call();
LOG.info("Result of {} in {} is {}", a, a.getClass(), result);
if (result != null) {
result.forEach(r -> resultProcessor.processResult(new PortValuePartEnvelope(r)));
}
return result;
} catch (Exception e) {
LOG.warn("Exception for {} in {}", a, runner.getClass(), e);
resultProcessor.processResult(Progress.failed(ctx.getId(), e));
throw new RuntimeException(e);
}
};
Future<List<PortValuePart>> p = pool.submit(runnerCallable);
} else {
LOG.warn("No runner found for activity {}", a);
resultProcessor.processResult(Progress.failed(ctx.getId(), new RuntimeException("No runner found for activity " + a)));
throw new RuntimeException("No runner found for activity " + a);
}
});
pool.shutdown();
try {
pool.awaitTermination(WAIT_TIME_MILLIS, TimeUnit.MILLISECONDS);
resultProcessor.processResult(Progress.running(ctx.getId(), progressAfterRan));
} catch (InterruptedException e) {
throw new PlatformException("Execution interrupted.");
}
}
Note that ExecutorService.awaitTermination doesn't throw an exception if it times out; it just returns false. If you want to make sure that the next calls don't run concurrently with these ones, you should probably use the return value, and maybe throw an exception (and kill the tasks) if it's taking way too long.

How to throw an error with transaction java

I'm doing something like this:
try {
client.restoreFromClusterSnapshot(req);
} catch (AmazonRedshiftException e) {
txUtils.execute((ts) -> {
redshiftDto.setStatus(ResourceStatus.FAILED);
redshiftDto.setStatusDetails(e.getMessage());
redshiftDto.setUpdatedOn(Timestamp.from(Instant.now()));
this.rdao.merge(redshiftDto);
return null;
});
LOGGER.error("CANNOT START REDSHIFT- " + e.getErrorMessage());
throw new AmazonRedshiftException( "CANNOT START REDSHIFT- "
+ e.getErrorMessage());
}
In this code, I'm not able to set database variable if I'm throwing an error because it is terminating my transaction. If I'll comment that throw it will work and my database value will be set. But I'll not able to throw anything. How can I do both- (throwing and setting value in DB)
What I'd do is make use of the finally clause.
AmazonRedshiftException exception = null;
try {
cluster = client.restoreFromClusterSnapshot(req);
} catch (AmazonRedshiftException e) {
exception = e;
LOGGER.error("CANNOT START REDSHIFT- " + e.getErrorMessage());
throw new AmazonRedshiftException( "CANNOT START REDSHIFT- "
+ e.getErrorMessage());
} finally {
if(exception != null) {
txUtils.execute((ts) -> {
redshiftDto.setStatus(ResourceStatus.FAILED);
redshiftDto.setStatusDetails(exception.getMessage());
redshiftDto.setUpdatedOn(Timestamp.from(Instant.now()));
this.rdao.merge(redshiftDto);
return null;
});
}
}

How can I catch a runtime exception from a EJB?

I have a very curious situation.
I'm trying to execute EJB's method and returns the result with JAX-RS
public Service readSingle(...) {
try {
service.query(...);
} catch (final NoResultException nre) {
throw new NotFoundException(...);
} catch (final NonUniqueResultException nure) {
throw new BadRequstException(...);
}
}
The query method requires some values and a BiFuction and a Function.
The actual call looks like this.
try {
return serviceService.<Service>query(
id,
ofNullable(matrixParameters.getFirst("onid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("tsid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("sid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("number"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("programId"))
.orElse(null),
operatorId,
(builder, root) -> emptyList(),
TypedQuery::getSingleResult);
} catch (final NoResultException nre) {
throw new NotFoundException(
"no entity idnetified by " + serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
} catch (final NonUniqueResultException nure) {
throw new BadRequestException("multiple entities identified");
}
Ok I passed TypedQuery::getSingleResult and I expect NonUniqueResultException should be caught when it has to be thrown.
But Payara keep responding with 500 and the log shows that the NonUniqueResultException has never caught by the code.
I disabled my ExceptionMappers the the results are same.
Ok. I figured it out. I had to do this.
try {
// execute EJB
} catch (final EJBTransactionRolledbackException ejbtre) {
Exception leaf = ejbtre;
try {
for (Exception c;
(c = ((EJBException) leaf).getCausedByException()) != null;
leaf = c);
} catch (final ClassCastException cce) {
}
logger.severe("causedByException: " + leaf);
if (leaf instanceof NoResultException) {
throw new NotFoundException(
"no entity idnetified by " + serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
} else if (leaf instanceof NonUniqueResultException) {
throw new BadRequestException(
"multiple entities identified by "
+ serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
}
throw new InternalServerErrorException(ejbtre);
}
This is far nasty beyond I've expected. The EJB's method design is not good.
Is there any way to do this more simply?
Let me introduce one of my utility class I used to justify myself.
public final class EJBExceptions {
private static final Logger logger
= getLogger(EJBExceptions.class.getName());
public static Stream<Exception> causedByExceptions(EJBException ejbe) {
final Stream.Builder<Exception> builder = Stream.builder();
while (ejbe != null) {
final Exception causedByException = ejbe.getCausedByException();
if (causedByException != null) {
builder.add(causedByException);
} else {
break;
}
if (causedByException instanceof EJBException) {
ejbe = (EJBException) causedByException;
} else {
break;
}
}
return builder.build();
}
public static Optional<Exception> lastCausedByException(
final EJBException ejbe) {
return causedByExceptions(ejbe).reduce((first, second) -> second);
}
private EJBExceptions() {
super();
}
}

jssc serialPort.readBytes(1) doesn't work (the same) on all COM-ports

I've got this weird problem that my software doesn't read the byte it sent when using the real COM5 or COM6, but when using a RS232 tot USB cable (which came up in Windows as COM12) it did work. Connected to the COM-port are two wires that will tell whether the door of the device is opened or not.
How can it be that the following code works on COM12 (a virtual COM-port), but not on COM5 and COM6 (real COM-ports) and when using putty and entering characters when the door is closed all three show the entered characters. It's the same behavior for all 3 ports with putty, but the software only works when it's connected to the vrtual COM-port that's made up by the Serial2USB cable ...
The problem occurs at a computer with 32-bit version of Windows 7 Embedded.
public void continuouslyCheckConnection() {
new Thread() {
public void run() {
while(true) {
if (hasStarted) {
sendByte();
int newStatus = readWithPossibleDelay(100);
logger.debug("new doorreader status: " + newStatus);
if (latestStatus != newStatus) {
latestStatus = newStatus;
if (newStatus == 0)
mainController.getScreensController().doorOpened();
}
}
try {
Thread.sleep(100);
} catch(InterruptedException ie) {
logger.error("DoorReader; InterruptedException in continuouslyCheckConnection: " + ie.getMessage());
}
}
}
}.start();
}
public void sendByte() {
try {
serialPort.writeByte((byte)0x01);
} catch(SerialPortException spe) {
logger.error("DoorReader; SerialPortException in sendByte: " + spe.getMessage());
}
}
private synchronized int readWithPossibleDelay(int delay) {
Callable<Integer> readTask = new Callable<Integer>() {
#Override
public Integer call() throws Exception {
byte[] byteArray = serialPort.readBytes(1);
int readInt = byteArray[0];
return readInt;
}
};
Future<Integer> future = executor.submit(readTask);
try {
return future.get(delay, TimeUnit.MILLISECONDS);
} catch (ExecutionException ee) {
logger.error("DoorReader; ExecutionException in readWithPossibleDelay: " + ee.getMessage());
} catch (InterruptedException ie) {
logger.error("DoorReader; InterruptedException in readWithPossibleDelay: " + ie.getMessage());
} catch (TimeoutException te) {
// ignore, this returns 0 which is okay
}
return 0;
}
I';ve also found somewhere that explicitly setting
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
might help, but it didnt change anything

Categories

Resources