is it possible to catch a fatal xml exception in java? - java

When i do DOM XML Schema validation i get this error when there is a syntax error in my deliberately-incorrect test file.
[Fatal Error] :10:3: The element type "gizmos" must be terminated by the matching end-tag "</gizmos>".
However, I want to catch this so that it wouldn't give the red fatal error warning, instead a message that says something like "your xml is not valid." Is it possible?
Thanks,

I believe you can catch Throwable to handle your scenario
try{
....
....
....
}catch (Exception e) {
e.printStackTrace();
}catch (Throwable t) {
t.printStackTrace();
}

Errors can not be catched, only Exceptions can be catched.
According to Java Docs :
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.
But still, you can catch Throwable to catch any error. That is not recommended though.
catch (Throwable e) {
//e.printStackTrace();
}

You can catch a Throwable (Error extends Throwable):
try {
//...
} catch(Throwable e) {
//...
}
Please note that it's often recommended not to do it. You can read more about it here: When to catch java.lang.Error?.

If you are using the JAXP validation API then you can nominate an ErrorHandler to receive notification of errors. With this you can change what messages are displayed and where they are displayed.

Related

Sonarcloud alerts "not enough arguments" when logging exceptions using SLF4J

I manage an open source project in Java and have about 20 places in my code where I log exceptions using the following pattern (slf4j version 1.7.30)
private static final Logger logger = LoggerFactory.getLogger();
...
try {
interfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException ex) {
logger.error("Socket exception when retrieving interfaces: {}", ex);
}
or similarly
try {
// stuff
} catch (IOException ioe) {
logger.error("Server error: {}", ioe);
}
Starting today, the SonarCloud automated code quality review has begun flagging these with rule java:S2275 (Printf-style format strings should not lead to unexpected behavior at runtime) with the specific message "Not enough arguments."
EDIT: Of note, this appears to consistently happen when an Exception is the final argument. The following pattern does not flag:
try {
// Server connection code
} catch (IOException e) {
logger.error("Server Connection error: {}", e.getMessage());
}
A review of this other StackOverflow question indicates that perhaps an extra argument for the exception is optional and would result in different behavior, so I'm not clear how that would apply here and why it would suddenly change.
Is there something I can/should do to better translate these exceptions to log messages (e.g., use getMessage() on all of them instead of relying on the automated toString() parsing), or is this a false positive?
(Sonar's list of my 20 issues linked here.)
This is pure conjecture, but each of the issues points to a log line that can be generalized as:
LOG.something(format, custom_arguments, exception)
where format has {} appearing count(custom_arguments) + 1 (the 1 reserved for exception).
As you've seen the linked answer, exceptions get treated specially by slf4j, so it's possible that due to some reason SonarCloud is doing the same thing. Unfortunately there's no documentation.
The "fix" would be to remove the final {} intended for the exception, so e.g.
LOG.error("boom: {}", e);
LOG.error("boom2 {}: {}", something, e);
becomes
// exceptions handled in a special way
LOG.error("boom", e);
LOG.error("boom2 {}", something, e);

What is a IOException, and how do I fix it?

What are IO Exceptions (java.io.IOException) and what causes them?
What methods/tools can be used to determine the cause so that you stop the exception from causing premature termination? What does this mean, and what can I do to fix this exception?
Java IOExceptions are Input/Output exceptions (I/O), and they occur whenever an input or output operation is failed or interpreted. For example, if you are trying to read in a file that does not exist, Java would throw an I/O exception.
When writing code that might throw an I/O exception, try writing the code in a try-catch block. You can read more about them here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Your catch block should look something like this:
try {
//do something
}catch(FileNotFoundException ex){
System.err.print("ERROR: File containing _______ information not found:\n");
ex.printStackTrace();
System.exit(1);
}
Here you go https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
IOException is thrown when an error occurred during an input-output operation. That can be reading/writing to a file, a stream (of any type), a network connection, connection with a queue, a database etc, pretty much anything that has to do with data transfer from your software to an external medium.
In order to fix it, you would want to see the stack trace of your exception or at least the message, to see exactly where the exception is thrown and why.
try {
methodThrowingIOException();
} catch (IOException e) {
System.out.println(e.getMessage()); //if you're using a logger, you can use that instead to print.
//e.printStackTrace(); //or print the full stack.
}
The error message that will be printed will likely show you what the issue is. If you add the error message here, I'll be able to give you more info on how to fix that specific IOException. Without that, no one can really give you a complete answer.
It is a very generic exception that a lot IO operation can cause. A best way is to read the Stack Trace. To continue the execution you can use the try-catch block to bypass the exception, but as you mention you should investigate into the cause.
To print the stack trace:
try {
// IO operation that could cause an exception
} catch (Exception ex) {
ex.printStackTrace();
}
IOException is usually a case in which the user inputs improper data into the program. This could be data types that the program can't handle or the name of a file that doesn't exist. When this happens, an exception (IOException) occurs telling the compiler that invalid input or invalid output has occurred.
Like others have said, you can use a try-catch statement to stop a premature termination.
try {
// Body of code
} catch (IOException e) {
e.printStackTrace();
}

Java JSoup Exception ignores try catch?

I've got a program that uses JSoup to connect to and parse data from a website. When the website fails to connect after the 10 second timeout I've given it, the JSoup method throws an UncheckedIOException. This may contain an IOException like "SSL Peer shut down unexpectedly" or "timed out" which are IOExceptions I've dealt with in the past. It's weird because it wrapped in a try catch:
Document document;
try {
document = Jsoup.connect("https://www.website.com").timeout(10000).maxBodySize(0).get();
} catch (Exception e) {
return false;
}
Elements elements = document.select("tr");
for (Element e : elements) {
System.out.println(e.text());
}
return true;
I've done all sorts of workarounds like wrapping the method in a try catch, making the method throw exception and handling it higher up, and the above where I've isolated the line causing the issue and wrapped only that in a try catch. I've tried catching Exception, IOException, UncheckedIOException, etc but it all eventually still causes the whole application to crash due to the error seeping through somehow.
I've never encountered something like this. How is it that a try catch can't deal with the error? Is it the way JSoup has set up their error system? This can't be right, can it? I'm using JSoup 1.11.2 if that helps, downloaded from https://jsoup.org/download.
The issue was that an Error was not being caught because I was trying to catch an Exception. JSoup throws an Object that extends Error, not Exception, so when I did
try {
} catch (Exception e) {}
I should have done
try {
} catch (Error e) {}

java: log exception being thrown

In java, I want to log the exception being thrown from a piece of code:
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad");
throw t;
}
The problem is that now my method must declare it throws throwable.
On the other hand, if I log the exception in a finally block, how do I know what exception is being thrown (and if any exception is being thrown at all).
You could at least write a catch for unchecked and n catch blocks for checked exceptions.
try{
..
}catch(RuntimeException e){
log(e);
throw e;
}catch(ExceptionException ..){
log(e);
throw e;
}
This will not change the signature of your method. Catching Errors is a bit of a smell. Well, logging and throwing exception is a smell, too. This will duplicate error messages.
Advance exception handling is a feature that was removed from project coin in JDK 7.
This seems to be the wrong place to log the exception. Either log it within doRiskyThing() when throwing it, or log it where it is supposed to be captured.
This should work:
try
{
doRiskyThing();
}
catch(RuntimeException e)
{
log.warn("too bad");
throw e;
}
catch(Exception e)
{
log.warn("too bad");
throw new RuntimeException(e);
}
catch(Error e)
{
log.warn("too bad");
throw e;
}
But it's ugly and I'd rather have a single catch block that catches everything and logs it at the top level of the app, with no re-throwing. The stack trace lets you pinpoint the problem anyway.
Catching Throwable in itself is already bad practice (and flagged as such by many code quality checking tools). Wrapping it in a RuntimeException and rethrowing it? Terrible! The whole point of having an exception hierarchy is undermined by this.
The 'trend' away from checked exceptions is actually a bit more subtle. Between architectural layers (or for example at a framework API boundary) it is common practice to define one or more meaningful exception types and wrap any implementation-specific errors in them (take a look at Spring or Hibernate for example).
Making exceptions checked or not is a matter of style. If there is a good chance that the caller will be willing and able to handle the error condition then I make it checked (e.g. concurrent update detected), otherwise unchecked (e.g. database connection error). Unchecked exceptions should 'bubble' up through your application code (i.e. not be caught) and handled at a high level by displaying some sort of error page/screen.
You can log the Throwable, and throw a RuntimeException.
In Java, you have to declare any exception that your method might itself throw, because it's considered part of the method's signature.... that is, apart from RuntimeException, which avoids that rule. The RuntimeException can give the message of the Throwable as part of its message, if you like.
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad, exception thrown: " + t.getMessage());
throw new RuntimeException("Throwable exception was thrown, message: " + t.getMessage());
}
Beware however that this may be considered bad practice, and for more long-term code it's recommended that you throw a non-runtime exception and define it in the method's signature.

Why is "java.lang.OutOfMemoryError: Java heap space" not caught?

I have a thread in a Java web application that causes a java.lang.OutOfMemoryError: Java heap space exception, but the try/catch block does not catch the error.
Sample code:
private void doSomeWork()
{
try
{
processData(); //Causes OutOfMemoryError
System.out.println("This line does not execute");
}
catch (Exception e)
{
System.out.println("Exception. This line does not execute.");
//Log error
}
finally
{
System.out.println("finally. This line does execute");
System.out.println("Thread name: " + Thread.currentThread().getName());
}
}
Output:
finally. This line does execute
Thread name: _Worker-8
Exception in thread "_Worker-8" java.lang.OutOfMemoryError: Java heap space
...
Background:
I recently took over this Java project and I'm trying to get up to speed with Java and this project. I'm a C# developer, so I'm not yet familiar with this project or Java.
I know I can fix the error using the -Xmx setting, but I'm interested in catching this error so I can log it. The error is not showing up in any of the logs files, and the output is being shown in the console in debug mode in Eclipse.
Because OutOfMemoryError is an Error, not an Exception. Since OutOfMemoryError isn't a subclass of Exception, the catch (Exception e) doesn't apply.
OutOfMemoryError does extend Throwable, however, so you should be able to catch it. Here's a SO discussion on when (if ever) you should catch Errors. Generally, since you can't do anything about it, the recommendation is to not bother catching Errors in production code. But given a special case where you're trying to debug what's going on, it might be helpful.
java.lang.OutOfMemoryError doesn't extends java.lang.Exception so it's not an Exception. OutOfMemoryError extends java.lang.Error. If you want to catch Error try this:
private void doSomeWork()
{
try
{
processData(); //Causes OutOfMemoryError
System.out.println("This line does not execute");
}
catch (Error e)
{
System.out.println("Exception. This line does not execute.");
//Log error
}
finally
{
System.out.println("finally. This line does execute");
System.out.println("Thread name: " + Thread.currentThread().getName());
}
}
Note: Exception and Error extends Throwable so you you can also use Throwable to catch both.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html
An "~Error" is not an "~Exception".
You have to catch "Error" or "Throwable"
OutOfMemoryError extends VirtualMachineError while Exception extends Throwable directly. So it is not being caught as per Java specs. IF you're looking to catch all exceptions, add catch (Throwable e) to the clause and you'll have it.
What I will usually do is add an 'UncaughtExceptionHandler' to a Thread so if anything leaks by you at least have a chance to log the issue and maybe do some cleanup.

Categories

Resources