Is there no way (regardless of how "hacky" it is) to detect when Java's System.err has been written to in order to be able to execute logic if and when this happens? — I'm currently working with a custom subclass of Thread (let's call it SwallowingThread) which swallows a number of exceptions in its implementation of Thread.run() in a manner similar to the following code:
public final class SwallowingThread extends Thread {
...
#Override
public void run() {
ServerSocket socket = new ServerSocket(80, 100);
try {
Socket connected = socket.accept();
// Do stuff with socket here
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In my code, however, I want to be able to handle cases of UnknownHostException and IOException which occur while using an instance of SwallowingThread; Is there no way to detect that this catching and printing to standard error after it has occured? — I had originally tried writing a UncaughtExceptionHandler to do this only to find out that it isn't catching the exceptions because they were swallowed rather than simply being e.g. wrapped in a RuntimeException and thrown onward.
Of course, a "better" way of solving this problem is to re-write the logic for the class, but is there no quick-and-dirty way of solving this issue without having to touch SwallowingThread?
You can implement your own class (I call it DelegatingErrorPrintStream) derived from PrintStream which notifies you if there's new output, and then delegates to System.err
And now you can set YOUR DelegatingErrorPrintStream as output stream for System.err using
System.setErr(err);
Full example including usage:
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class ErrorNotifierExample {
private static final class ErrorDelegatingPrintStream extends PrintStream {
public ErrorDelegatingPrintStream(PrintStream defaultErr)
throws FileNotFoundException, UnsupportedEncodingException {
super(defaultErr);
}
#Override
public void print(boolean b) {
super.print(b);
notifyListener(b);
}
#Override
public void print(char c) {
super.print(c);
notifyListener(c);
}
#Override
public void print(int i) {
super.print(i);
notifyListener(i);
}
#Override
public void print(long l) {
super.print(l);
notifyListener(l);
}
#Override
public void print(float f) {
super.print(f);
notifyListener(f);
}
#Override
public void print(double d) {
super.print(d);
notifyListener(d);
}
#Override
public void print(char[] s) {
super.print(s);
notifyListener(s);
}
#Override
public void print(String s) {
super.print(s);
notifyListener(s);
}
#Override
public void print(Object obj) {
super.print(obj);
notifyListener(obj);
}
#Override
public PrintStream append(CharSequence csq, int start, int end) {
notifyListener(csq); // TODO will need some special handling
return super.append(csq, start, end);
}
private void notifyListener(Object string) {
// TODO implement your handling here. System.out printing is just an
// example.
System.out.println(String.valueOf(string));
}
}
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
ErrorDelegatingPrintStream errReplacement = new ErrorDelegatingPrintStream(System.err);
System.setErr(errReplacement);
System.err.println("TEST01");
throw new RuntimeException("just a test output for ERROR handling");
}
}
As several persons already suggested, you may go with a custom PrintStream.
It will replace the standard error stream but also encapsulate it and call it when needed.
Since the exceptions and stack traces are what you are interested in, overriding print(String) should be enough (println(String) already calls this method + newLine()).
The stream could look like that :
import java.io.PrintStream;
public class CustomPrintStream extends PrintStream {
public CustomPrintStream(final PrintStream out) {
super(out);
}
#Override
public void print(final String s) {
super.print(s);
// some String is written to the error stream, Do something !
}
}
You would use it that way, at the beginning of your application, just call
System.setErr(new CustomPrintStream(System.err));
Related
I have one method throwing MyOwnException, but we all know that it is suggested to wrap it with RunTimeException when we are calling within streams. So here is the implementation I have done:
package com.company;
import java.util.Arrays;
import java.util.List;
public class Main {
static class MyOwnException extends Exception {
}
public static void main(String[] args) throws MyOwnException {
// write your code here
List<String> input = Arrays.asList("bad", "ok");
try {
long i = input.parallelStream().map(s -> tryIfBadStringThrowExceptionIdentity(s)).count();
}
catch (RuntimeException re) {
String s = re.getMessage();
if(s.equalsIgnoreCase("MyOwnException"))
throw new MyOwnException();
}
}
private static String ifBadStringThrowExceptionIdentity(String s) throws MyOwnException {
if(s.equalsIgnoreCase("bad"))
throw new MyOwnException();
else return s;
}
private static String tryIfBadStringThrowExceptionIdentity(String s) {
try {
return ifBadStringThrowExceptionIdentity(s);
} catch (MyOwnException e) {
throw new RuntimeException("MyOwnException");
}
}
}
Passing string and then again creating exception back via the string, is it best practices, or you have some elegant solution to this? if this is best way, am I the only one started disliking Java? And by the way, why only RunTimeException is valid for Streams related exception, does it impact code speed converting string back to exception?
Do not use an existing exception type like RuntimeException that can have other causes and don’t rely on something as fragile as strings for identifying your issue. Just use a dedicated exception type for carrying an underlying checked exception to the initiator:
static class UncheckedMyOwnException extends RuntimeException {
UncheckedMyOwnException(MyOwnException original) {
super(original);
}
#Override
public MyOwnException getCause() {
return (MyOwnException)super.getCause();
}
}
public static void main(String[] args) throws MyOwnException {
List<String> input = Arrays.asList("bad", "ok");
try {
// do not rely on count() for processing code; starting with JDK 9 it will skip
// map operations not needed to determine the count
input.parallelStream().map(s -> tryIfBadStringThrowExceptionIdentity(s))
.forEach(System.out::println);
}
catch(UncheckedMyOwnException re) {
throw re.getCause();
}
}
private static String ifBadStringThrowExceptionIdentity(String s) throws MyOwnException {
if(s.equalsIgnoreCase("bad"))
throw new MyOwnException();
else return s;
}
private static String tryIfBadStringThrowExceptionIdentity(String s) {
try {
return ifBadStringThrowExceptionIdentity(s);
} catch(MyOwnException e) {
throw new UncheckedMyOwnException(e);
}
}
Note that this will throw the original exception, so it includes the actual origin in its stack trace. But when the exception happened in a worker thread, it will not include the initiator, i.e. the call chain that started the stream operation. To ensure that both parts are always included, you would have to use something like
catch(UncheckedMyOwnException re) {
MyOwnException withInitiator = new MyOwnException();
withInitiator.initCause(re.getCause());
throw withInitiator;
}
Using a dedicated unchecked exception type to carry a checked exception, is an established pattern, see for example UncheckedIOException.
I would like to two have two different methods running in catch and final blocks. I have found AutoCloseable interface, but I need something to fire in case of exception only.
Like:
SomeService service = CreateService().andOpenTransaction()
try {
service.doSomeMessyThingsInsideDB();
} catch (Exception e) {
service.rollbackTransaction();
throw e;
} finally {
service.closeConnection();
}
Is there any way to make it simpler? As I said I am familiar with AutoCloseable, but it helps me only with finally block. I still cannot use it inside the catch.
Well you could define your own interface, and then some static runner method:
public interface ErrorHandlingCloseable extends AutoCloseable {
void run() throws Exception;
void onError(Exception e);
static void execute(ErrorHandlingClosable ehc) throws Exception {
try(ErrorHandlingClosable temp = ehc) {
ehc.run();
} catch(Exception e) {
ehc.onError(e);
throw e;
}
}
}
Which you then could then call like this:
SomeService service = CreateService().andOpenTransaction();
ErrorHandlingCloseable.execute(new ErrorHandlingCloseable() {
public void run() throws Exception { service.doSomeMessyThingsInsideDB(); }
public void onError(Exception e) { service.rollbackTransaction(); }
public void close() throws Exception { service.closeConnection(); }
});
But you see, it's still messy.
You could even implement this interface in your SomeService but then you're restricted that the run() method will always call doSomeMessyThingsInsideDB().
Another way but still similar would be to use Java8 and create a helper functional interface:
public interface ThrowingRunnable {
void run() throws Exception;
}
And then a static method somewhere:
public static void execute(ThrowingRunnable action,
ThrowingRunnable onCatch,
ThrowingRunnable onFinally) throws Exception {
try(AutoCloseable ao = onFinally) {
action.run();
} catch(Exception e) {
onCatch.run();
throw e;
}
}
The interesting part is probably this: try(AutoCloseable ao = onFinally), which "registers" your onFinally method to be called when finally is reached.
This could then be called like this:
execute(
service::doSomeMessyThingsInsideDB,
service::rollbackTransaction,
service::closeConnection
);
You said you are familiar with AutoCloseable, but you don't use it.
Have you considered using try-with-resources statement?
Your code can be simplified to:
try (SomeService service = CreateService().andOpenTransaction()) {
service.doSomeMessyThingsInsideDB();
} catch(exception e){
service.rollbackTransaction();
throw e;
}
Oracle has great doc for that, including examples.
Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
Answering your question, this is as simple as it can get.
If your class doesn't implement Closeable then you can either implement it or use finally.
First step: Handling the exception
You evidently want the exception handled before some close. Then you need inside a try-with-resources to handle the exception.
/** throws RuntimeException */
void process(Callable<Void> work, Consumer<Exception> onFail) {
try {
work.call();
} catch (Exception e) {
onFail(e);
}
}
try (SomeService service = CreateService().andOpenTransaction()) {
process(() -> service.doSomeMessyThingsInsideDB(),
e -> {
service.rollbackTransaction();
throw new IllegalStateException(e);
});
}
This is not very satisfactory, but again also integrating the AutoCloseable, might give too few use-cases.
Second step: with AutoCloseable
<SV extends AutoCloseable> void processAutoClosing(Supplier<SV> serviceFactory,
Callable<Void> work, Consumer<Exception> onFail) {
try (SV service = serviceFactory.get()) {
process(work, onFail);
}
}
processAutoClosing(...);
I want to open Task Manager and click on its tabs like 'Process','Performance','App history', etc. by using core java only.
Tried to begin with
public class Desktop1 {
public static void main(String[] args) throws IOException {
Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"Taskmgr.exe");
}
}
Exception in thread "main" java.io.IOException: Cannot run program "C:\WINDOWS\system32\Taskmgr.exe": CreateProcess error=740, The requested operation requires elevation
There are multiple ways of achieving this. The simplest way is mentioned by #mkane in his comment. Programatically, this could be achieved in the following way:
Add following dependency to your application:
<dependency>
<groupId>com.vnetpublishing.java</groupId>
<artifactId>super-user-application</artifactId>
<version>0.0.5</version>
</dependency>
Now you can make your class extend SuperUserApplication class and override its run() as:
public int run(String[] strings) {
try {
Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"Taskmgr.exe");
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
Now call static run(...) of class SU passing in the instance of the class extending SuperUserApplication. Here is a complete example for your reference:
public class Main extends SuperUserApplication {
public static void main(String[] args) {
SU.run(new Main(), args);
}
// #Override
public int run(String[] strings) {
try {
Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"Taskmgr.exe");
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
}
For example:
try {
Thread.sleep(333);
} catch (InterruptedException e) {
e.printStackTrace();
}
can I use the above try/catch in some kind of way using a created method like trySleep(Thread.sleep(333)); that'll do the exact same as the original try?
A example of use:
public class Test implements Runnable {
public Test() {
Thread thisThread = new Thread(this);
thisThread.start();
}
#Override
public void run() {
while (true){
System.out.println("Testing");
trySleep(Thread.sleep(333));
}
}
public void trySleep(/*Thread object*/){
//Code for try/catch
}
public static void main(String[] args) {
new Test();
}
}
Of course the above code won't compile, it's just for the question.
The reason I want this kinda thing is because I find the try/catch things to be so messy and is quiet annoying to read.
You could wrap Thread.sleep in a function that re-throws any exception as a runtime exception (or any uncaught exception).
public static void trySleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted during sleep", e);
}
}
I don't get the question. If you add the three lines into the trySleep-method Body, you get a method, which will let the Thread sleep.
So the answer is yes.
By the way:
You wrote an endless sleeping loop
Yes, you can do this, but not exactly the way you describe it now. Wherever you use Thread.sleep() you will have to catch InterruptedException, so you would have to enclose the call in the method like this:
public void trySleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace(); //handle exception here
}
}
You can call this method like this: trySleep(333)
It is sometimes better to just add a throws declaration to your method though or to re-throw a more meaningful exception, unless you know that this is the location where it makes most sense to catch the exception.
You could wrap your sleeping code in another method as you sugested.
public static void trySleep(Thread target, long millis){
try{
target.sleep(millis);
} catch(InterruptedException e) {
System.err.println("Exception Occurred while trying to sleep!");
}
}
You probably shoud do this, in fact, as making code modular is the right way to go.
One important thing I think you really need to consider (in addition to the answers to how to do this properly), is to understand what code you're calling.
In your code:
#Override
public void run() {
while (true){
System.out.println("Testing");
trySleep(Thread.sleep(333));
}
}
Particularly this line:
trySleep(Thread.sleep(333));
You're basically saying
Call the method Thread.sleep() with a value of 333.
Whatever value Thread.sleep() returns, pass that to another method.
But the Javadocs say it's a void method.
Also in your code:
public void trySleep(/*Thread object*/){
//Code for try/catch
}
You should check this stackoverflow post out for why this is not good practice (as you'll be trying to invoke a static method on an instance object).
Others have answered your question on this, but I highly recommend brushing up on these areas as it indicates you may likely be missing critical knowledge of some important concepts.
You can use java 8's lambda expressions to do something similar to this:
#FunctionalInterface
interface InterruptedExceptionRunnable {
void run() throws InterruptedException;
}
void trySleep(InterruptedExceptionRunnable exRunnable) {
try {
exRunnable.run();
} catch(InterruptedException ex) {
ex.printStackTrace();
}
}
which allows you to write this:
trySleep(()->Thread.sleep(333));
Yes, you can do basically this with Java 8 lambdas.
class Example {
#FunctionalInterface
interface InterruptableRunnable {
void run() throws InterruptedException;
}
static void tryRun(InterruptableRunnable r) {
try {
r.run();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// passing a lambda
tryRun( () -> Thread.sleep(333) );
}
});
t.start();
// passing a method reference
tryRun(t::join);
}
}
In Java, all the standard blocking methods can be interrupted by calling Thread.interrupt(), but what if we have Java bindings wrapping a native library which does its own I/O? How then should the native code hook into the Thread and respond to calls to Thread.interrupt()?
Example code
For a full writeup, including runnable sample code, see https://github.com/NWilson/javaInterruptHook.
How does Thread.interrupt() work?
In Sun's JRE (and OpenJDK), interrupt() is able to wake up a few low-level operations itself, such as waiting on a monitor (Object.wait()), and provides an internal hook for higher-level code to be notified of the interruption. This is provided through JavaLangAccess.blockedOn(), which can actually be called directly by your code through sun.misc.SharedSecrets, if you're willing to use Sun-specific implementation details.
As far as I can tell, there's only one public, documented way to register for that notification, which is using java.nio.channels.spi.AbstractSelector. This is a partial implementation of Selector which does the dirty work for you of hooking up the JavaLangAccess.blockedOn() notification to the selector's wakeup() method.
How to implement this all
Implement AbstractSelector to make your own selector; most of the methods are not relevant so just ignore them and put in stubs to shut up the compiler. When you are about to enter your JNI blocking method, call the AbstractSelector begin() method, then call end() when the JNI call has returned.
The selector should cancel the JNI method in its implementation of wakeup().
Rough code
(For a full running example see the github repo linked at the top.)
class NativeTask {
public NativeTask() {}
public void doTask()
throws InterruptedException {
NativeTaskSelector selector = new NativeTaskSelector(this);
try {
selector.registerStart();
doTask0(); // native method
if (Thread.interrupted())
throw new InterruptedException();
} finally {
selector.registerEnd();
try { selector.close(); } catch (IOException impossible) {}
}
}
/* The long-running native operation. */
native private void doTask0();
public void wakeupTask() { wakeupTask0(); }
/* A way to cause the native operation to wake up. */
native private void wakeupTask0();
}
class NativeTaskSelector extends AbstractSelector {
protected NativeTaskSelector(NativeTask task_) {
super(null);
task = task_;
}
public void registerStart() { begin(); }
public void registerEnd() { end(); }
final private NativeTask task;
#Override
public Selector wakeup() {
task.wakeupTask();
return this;
}
#Override
protected void implCloseSelector() throws IOException {
}
#Override
protected SelectionKey register(AbstractSelectableChannel arg0, int arg1,
Object arg2) {
throw new UnsupportedOperationException();
}
#Override
public Set<SelectionKey> keys() {
throw new UnsupportedOperationException();
}
#Override
public int select() throws IOException {
throw new UnsupportedOperationException();
}
#Override
public int select(long arg0) throws IOException {
throw new UnsupportedOperationException();
}
#Override
public int selectNow() throws IOException {
throw new UnsupportedOperationException();
}
#Override
public Set<SelectionKey> selectedKeys() {
throw new UnsupportedOperationException();
}
}