Can't open java application when ran as executable jar - java

I had a strange problem today... I'm going to make a simplified example since it "worth a thousands words" :D
public class Application() {
public static void main(String[] args) {
try {
A a = new A(); // this may throw exceptions
// (which will cause an ExceptionInInitializerError)
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, "Oooops!");
System.exit(1);
}
}
}
Since it's a stand-alone application with a Swing GUI, my goal is to give a message to the user in case of any problems (in this case at startup)... the code above works in Eclipse IDE but when I export the project as executable jar by double-clicking on it, well, it just won't open.
So I try to execute it in cmd with java -jar application.jar and it prints in the shell that there was an ExceptionInInitializerError.
Why the error was not caught?
It doesn't work even if I specify catch (ExceptionInInitializerError e).
EDIT:
After more indepth debugging, I found out that this problem only happens when two particular exceptions occur and the latter occurs in the catch block of the former.
I corrected the bug by changing the order of some checks that I do on startup.
The problem btw should never happen since it was originated by a volountary mistake of the JDBC driver class name to load in a static block.
Well, at least it made me clearly understand why constructors and static initialization blocks should not throw exceptions: it makes debugging almost impossible in the case in which the class that throws the exception is used by many classes, since it may become very hard to find out when the class is loaded.

I can think of three possible explanations for an ExceptionInInitializerError not being caught in your example:
It could be being thrown by JOptionPane.showMessageDialog(null, "Oooops!");
It could be thrown before main is called.
It could be thrown on a different stack.
In fact, I think that the 2nd one is the most likely, as ExceptionInInitializerError is thrown when some unchecked exception is thrown (and not caught) during the initialization of a class. That could well be happening before you enter the try block.

Related

Forcing java to make a compile error with the user input as message

I Don't know whether it is possible in java or not; I want to get an input from user (from System.in) and then throw a compile error with that input. I mean if the user inputted the text "HELLO" then the program should throw a compile error: Compile Error: HELLO. I want an error that actually make the program stop executing at that point with that message.
Is this possible? If yes, How?
Actually I want to make a compile error during run-time!
The code will be like this:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
//compileError(str); this part must be completed
}
}
Is this possible?
What you are referring to is Exceptions not a compilation error. Compilation error is when there is something wrong in the syntax of your code and the Java compiler fails to generate byte code for your program for the JVM to execute it. So that happens before you can run the program.
So you can use an instance of a RuntimeException or any sub class of it in Java to terminate your program when "HELLO" is used as the input, here in my sample code InputMismatchException is thrown if the input is "HELLO", this exception being a sub class of RuntimeException or unchecked exception doesn't require the programmer to add a throws clause or handle it explicitly:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
if("HELLO".equals(str)){
throw new InputMismatchException("This input is not allowed");
}
}
You can make your program stop executing at that point. For example:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
if (str.equals("HELLO")) {
System.out.println("Compile Error: " + str);
System.exit(1);
}
// Do something else.
}
}
Another way to do it is to throw an exception ... except than you will get an exception stacktrace as well as a message. In the context you are doing this, it probably doesn't matter.
Note that there are some potential problems with this:
If the judge intercepts all output, then it may not be possible to get hold of the messages that your application produces.
The judge may feed your application different inputs each time it judges it.
However, this is not a real compile error. Indeed, it doesn't make sense for your program to generate a real compile error.
Compile errors occur when code is being compiled, and they are output by the compiler. But a Java application cannot read input (from the user or the "judge") at compile time. It can read input at runtime ... but then it is too late for a compilation error.
You seem to have your terminology confused. I suggest you read these articles to understand what the various terms mean:
Compilation Error or Compiler Error - https://en.wikipedia.org/wiki/Compilation_error
Runtime Error - https://techterms.com/definition/runtime_error
Exception - https://techterms.com/definition/exception
Your commented thus:
Think that you are given a program that you don't know what it should do and it pass some tests on an online judge. You know what the input could be but don't know in which order they come and you should get the test cases without actually accessing the online judge's test cases. I want to make my program give me some errors to find out what is in each test case.
and
I just have a working program and want to extract the input from online judge.
That is not a compilation error you are talking about. That is a runtime error, because you want / need it to happen when your program runs. Please refer to the links above for explanations of these terms.
If your intent is to print a message and exit out of program you can do something like following
...
System.err.println("Your input has resulted in an error, program will terminate");
/* You can change the above text with whatever you want */
System.exit(1);
Alternately, you can always throw an object of Exception (or an object of a class derived from it) and don't catch it anywhere in your program when it bubbles, program will terminate.
/* add throws Exception in your main method */
throw new Exception("Your input has resulted in an error, program will terminate")
However it's not clear why you would specially look for throwing Compile error. Compile time errors are thrown by compiler when compiling a program. During execution you neither expect them nor try to throw them.
You cannot throw a compile error when your code is executing. I think you meant a Runtime error that cause your code to fail at runtime.
Try something like this:
throw new RuntimeException(str);
You can also catch this 'error' if you surround your code with try/catch clauses.
try {
// get the input
throw new RuntimeException(str);
} catch (RuntimeException ex) {
// ex contains the error details
// ex.getMessage() will give you the user's input
}
RuntimeException is the most general exception for errors at runtime, you can use other exceptions, list of exceptions.

Usage of throws command in java

I know questions like this are everywhere, but I read a lot of things about this, and I still can't understand what the "throws" command do. I will be more specific now:
So, one of the examples I saw was this one, with the following code:
public class CatchThrow {
private static void throwsMethod() throws NumberFormatException {
String intNumber = "5A";
Integer.parseInt(intNumber);
}
private static void catchMethod() {
try {
throwsMethod();
} catch (NumberFormatException e) {
System.out.println("Convertion Error");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
catchMethod();
}
}
Now, if I remove the "throws NumberFormatException" from the "throwsMethod" method, the program will run the same, and will give the same results. Actually, every example with the throws command that I saw did the same, so I can't really understand why use it.
I'm using the Eclipse IDE, version 4.7.2.
Normally your function exits at the end of the function or the return statement.
However, a function can also exit when it reaches a throw statement. If the exception subclasses Exception, the caller of the function must surround the function call with a try { } catch { } block. If the exception subclasses RuntimeException you may optionally surround the function call in a try catch block.
If you look at the JavaDoc for NumberFormatException: https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html will see it subclasses RuntimeException. This means your try-catch block is optional. The difference between the two program is this: With the try-catch block you will get Convertion Error printed to the console, without it, you will see the full stack trace. This is often called "swallowing the exception".
So basically, if an exception occurs and you don't want to handle that exception there, in that case you use the 'throw' keyword to simply just throw the exception if occurs.
Example: Here, in throwsMethod(), you are not taking care of the Exception Handling i.e. not using the try(), catch() blocks, you are just throwing it if there occurs any Exception. And you will land in catch() block if exception occurs in your throwsMethod().
To get better idea, you should read checked & Unckecked exceptions in Java. For Checked exceptions (happen at compile-time), we use 'throw' keyword and for Unchecked (Run-time), we use try() catch().
Example: NumberFormatException is an Unchecked exception, IOException is a Checked exception.
Read this for reference: https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/

The console in Eclipse (Java) does not output things in the correct/chronological order

Why is the output not in the correct order for the following test code:
public static void main(String[] args) {
boolean test = false;
try {
assert test: "will fail with -ea enabled in VM args" ;
} catch (AssertionError e) {
e.printStackTrace();
System.out.println("idk why you would use this but...");
}
System.out.println(test + " sneaks in between");
}
run this with "-ea" enabled in the VM arguments (run config)
randomly the output is either:
java.lang.AssertionError: will fail with -ea enabled in VM args
at Main.main(Main.java:31)
FOO
BAR
(should happen) or:
java.lang.AssertionError: ERROR
FOO
BAR
at Main.main(Main.java:31)
(should not happen) and sometimes:
java.lang.AssertionError: ERROR
FOO
at Main.main(Main.java:31)
BAR
I was messing around with "assert" when this happened. I know the code is complete nonsense but it may also happen with other setups.
Seconldy consoles are not really used too much in many programs as an official thing, mostly for debugging. But it is still weird.
Is this because the try catch is running on a different thread? or is the stuff happening so fast after eachother that one thing pushes out before the other thing?
I do notice adding a Thread.sleep(1); (which needs to be thrown or caught)
does make it always go in chronological order, so...
Why does it not print the code in chronological order?
printStackTrace() prints to the error out. How that chronologically lines up with the standard out is indeterminate. You can try calling flush() on System.out, but I can't assure you the result will ever be as you expect unless you specifically print the stack trace to standard out using one of the other available methods.

How to make runnable Jar programs that do not fail silently?

For the runnable Jar programs I create, I can read the unhandled exceptions if I run it from the command prompt (java -jar myprogram.jar).
Example code:
public static void main(String args[]) {
try {
EntireProgram();
} catch (Throwable t) {
throw new Error("somehow our error handling code has errors");
}
}
public static void EntireProgram() {
System.out.println(1 / 0);
}
Command line output:
However, if I run the Jar program by double-clicking it (expected of most end-users), the unhandled exceptions stay silent. I've noticed that this is in contrast to "native Windows programs" which I believe have unhandled exceptions handled by the OS default handler (modal dialog message):
The advantage of handling unhandled exceptions this way is that the user will know something wrong has happened (and perhaps report it, hopefully).
How can I make my program's unhandled exceptions be handled in such a way?
Why don't you add a single line like this in your catch block ..which will show you the error message irrespective of How you run your app.
javax.swing.JOptionPane.showMessageDialog(null,"Something is really wrong..Hence notifying you..");

Can an Error be handled?

public class StackTest {
public static void main(String[] args) {
show();
System.out.print("welcome back to maain");
display();
}
static void show(){
try{
show(); //recursion
}catch(StackOverflowError e){
System.out.print("error cought");
}
}
static void display(){
System.out.print("after stack overflow error");
}
}
In this program an StackOverflowError occurs but gets handled and the program does not terminated abnormally. why?
You can see this at http://ideone.com/vwSav
You can handle Errors because they are Throwable just like Exceptions.
Errors are designed to indicate problems outside your program's control, like OutOfMemoryError and StackOverflowError, but you can define your own errors, too.
Perhaps you are thinking that, or heard that, OutOFMemoryError can be caught but there's no guarantee you'll have enough space to execute the handler, so errors must in general not be something you can catch. In your case, though, you got away with it. No language rules were violated in the catching and handling of this error.
The real question is, should you catch them? Normally when an error, as opposed to an exception, is thrown, your application is very likely in an inconsistent state, making recovery a crapshoot at best. So be really, really careful. Better to forget it and let the app die though, since whatever is running after the handler is not guaranteed to be something you'd want to run.
Why would you expect it to terminate when you catch the exception (or rather the Error in this case)? What else would that catch block do?
You can catch and handle pretty much all error conditions, though usually you should only catch Exceptions.
You can catch any Throwable and it is up to the developer to handle it correctly. You can even handle ThreadDeath (triggered by a Thread.stop()) or another sub-class of Throwable (which is neither an Error or an Exception)
public class MyThrowable extends Throwable { } // checked "exception"
try {
throw new MyThrowable();
} catch (Throwable t) {
t.printStackTrace();
Thread.currentThread().stop(t); // rethrow blindly.
}
It will only be terminated abnormally if your exception is propagated all the way up to your main method and you don't handle it there. Usually happens for unchecked run time exceptions. If you want to terminate your program and shut down the VM you can call System.exit(int errorCode) in the catch block, there will be programmers which always complain here if that's done but that's a way to do it.
usually you don't catch Error, except for LinkageErrors, no class def found errors, unsatisfied link errors, incompatible class change errors..
also an outofmemory error (sometimes the stackoverflow exception) doesnot give control the catch block as there is no memory.

Categories

Resources