Undeclared exceptions in JNI - java

What happens if a JNI dll throws a Java exception, and the java method definition doesn't declare that exception (no throws clause)?
Code:
private native void jniDoSomething(int someValue);

Exception will be thrown anyway.
Just have checked this.
I think such behaviour is because that throws keyword doesn't affect the native code anyway. There is no ability to check if the native code throws the appropriate exception and even in header file there are no mentioning about exceptions.

Related

SonarQube error: Refactor this method to throw at most one checked exception

I am using SonarQube and it shows the following error:
Public methods should throw at most one checked exception.
// Noncompliant
public void delete() throws IOException, SQLException { /* ... */ }
// Compliant
public void delete() throws SomeApplicationLevelException { /* ... */ }
Does this means, SomeApplicationLevelException is a parent class and IOException and SQALException are derived from it? And we should throw the parent class exception? Thereby adhering to method throwing only 1 checked exception?
Because I have 2 exceptions that i have defined say for example Exception1 and Exception2 that extend Exception. And my method say, sampleMethod() throws them i.e,
public void sampleMethod() throws Exception1, Exception2 {
}
And the error is shown here. So should I have one class as parent (say MainException) and derive Exception1 and Exception2 from it and throw parent exception class? Like below:
public void sampleMethod() throws MainException {
}
Is the above solution proper?
If you have a method in your application that is declared as throws SQLException, IOException, you are probably leaking internal implementation details to your method's users. Specifically, you're saying:
Your method is implemented using JDBC and file I/O. Your users don't care how your method is implemented; they only care about what your method does.
Your method, including any future version of it, will never throw any other checked exception. If in future you change your method so that it might throw another checked exception, it will break backwards compatibility.
The advice is to create your own application-specific class (derived from Exception), and only throw that in your method. You can, if you like, wrap the SQLException or the IOException (or any other exception) inside your application-specific exception as the cause.
Note, however, that there is a school of thought that says Java checked exceptions are a bad idea (and one of the reasons C#, and more modern languages such as Kotlin, don't have checked exceptions).
UPDATE: the above answer related to the first version of the question (edit #1). The question was subsequently updated to point out that the two thrown exceptions were application-defined ones, so therefore much of the above rationale no longer applies. The answer to the updated question is explained in this post.
IOexception and sqlexception both are checked exception s,totally different from each other , now if we extend both from one exception and throw the parent exception , which is not a mandatory in java, it will be kind of misguiding the user of the api.
However, if you want to do it in ur app to avoid sonarqube error , you can catch all your specific exceptions and throw a custom exception wrapping the original exception information in exception message.
for example
try{
///piece of code that throws IOException and SQLException
}catch(IOException | SQLException ex){
throw new DataException(ex,"Any customized message you want");
}
This DataException will then will be included in the throws clause of method signature having this try catch.
DataException extends Exception class and by passing ex in the contructor you are wrapping the original exception in custom exception with your original exception info preserved.

Is disabling Checked Exceptions in Java possible?

I was reading an article about checked and unchecked Exceptions in Java and found this article/link:
https://projectlombok.org/disableCheckedExceptions.html
According to the article it's just a hack developed for javac.
Consider the code snippet below:
import java.io.*;
class Example
{
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("myfile.txt");
int k;
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}
}
Here I have to write public static void main(String args[]) throws IOException
because I am trying to open a file. Here "throws" clause is a must. Without it I will get an error. What if I am sure about the Existance of the file I am opening. i.e.myfile.txt in the mentioned location. At some point one can feel that few Checked Exceptions are not required for the code.
Is there any facility provided by Java to disable checked Exceptions according to the need?
Even after doing so much research I could not find a proper answer for it.
Is there any facility provided by Java to disable checked Exceptions according to the need?
No official facilities, but there are workarounds one can use when needed:
First, since there are both checked and unchecked exceptions in java, using unchecked exceptions might be an option. All exceptions which derive from RuntimeException are unchecked:
RuntimeException is the superclass of those
exceptions that can be thrown during the normal operation of the
Java Virtual Machine.
A method is not required to declare in its throws
clause any subclasses of RuntimeException that might
be thrown during the execution of the method but not caught.
Interesting read here, here.
Then there is type erasure which allows to throw a checked exception without declaring it.
This is what project lombok uses for #SneakyThrows
import lombok.SneakyThrows;
public class SneakyThrowsExample implements Runnable {
#SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
#SneakyThrows
public void run() {
throw new Throwable();
}
}
Use with caution:
Be aware that it is impossible to catch sneakily thrown checked types directly, as javac will not let you write a catch block for an exception type that no method call in the try body declares as thrown.
And lastly it's only the compiler which cares about checked exceptions, it's not part of the jvm at all. Once you're past the compiler stage anything is possible. So writing bytecode directly or using a version of javac with checked exceptions disabled completely bypasses them.
Other than hacking the compiler there is no option to disable checked exceptions I know of. Best you can do is catch the checked exception and rethrow it within a runtime exception if you don't want to force the client code to handle the checked exception.

What does the `throws IOExeption` do? [duplicate]

This question already has answers here:
What does "Throws" do and how is it helpful? [duplicate]
(5 answers)
Closed 7 years ago.
What does the throws IOExeption actually do when importing a file?
Example
public static void main(String args[]) throws IOException {
Scanner scanner = new Scanner(new File("C:\\Location"));
// more code
scanner.close();
}
throws indicates that a method requires a caller to either handle the exception, or allow the exception to continue being thrown up the call stack. The former requires the method that can throw the exception to be called in a try-catch block; the latter requires the calling method to include the type of exception (e.g. IOException) in its own method signature.
In your case, main(String[] args) includes the exception in its signature, meaning it does not plan on handling the exception but instead will pass it up the stack. Since main is the program's entry point, there is nothing else to handle the exception and the program would terminate.
In Java, the IO classes throws a checked exception called IOException, e.g. saying "File not found". A checked exception must be handled in a try-catch block or it must be allowed to bubble up to the caller of your method by declaring that your method may cause that exception to be raised.
In your book, there's no need to handle exceptions, so simply allowing the exception to bubble up is the easiest to do. You'll learn more about this later.
The throws IOExeption actually does not do anything when "importing" the file. Rather, it is relevant to what happens when you fail to "import" the file.
The Scanner class throws an IOException when the file could not be read for some reason. However, IOException is a checked exception. This means that Java demands that you handle the exception somehow in a try/catch block.
When you declare throws IOException, you are telling Java that you will not handle the exception, and instead allow it to bubble up, and leave the caller of your method to handle the exception instead.
In this particular case, you are already in the main method. So you will get a stack trace should be exception be thrown.
When you are stating that a method throws an exception you are actually saying that the code that is outside (the caller or his ancestors in the callstack) this method is the one that's gonna need to catch the exception (and maybe no one)
also, in your method, youre gonna need to use "throw" key word.
for example, a case when the calling code IS catching the thrown execption:
class example
{
static void method() throws IOExeption
{
// in this code section you use the Scanner and from inside its code an
// an IOExeption is thrown ( using "throw IOExecption;")
}
public static void main(String args[])
{
try
{
method();
}
catch (IOExeption ioe)
{
// handle it however you want
}
}
}

class newInstance propagates checked and unchecked exceptions - is it true?

According to this: https://docs.oracle.com/javase/tutorial/reflect/member/ctorTrouble.html
Class.newInstance() Throws Unexpected Exception
The ConstructorTroubleToo example shows an unresolvable problem in Class.newInstance(). Namely, it propagates any exception — checked or unchecked — thrown by the constructor.
This situation is unique to reflection. Normally, it is impossible to write code which ignores a checked exception because it would not compile. It is possible to wrap any exception thrown by a constructor by using Constructor.newInstance() rather than Class.newInstance().
Below I have a code that doesnt catch any unchecked (RuntimeEcxeption/Error) exception I commented them and it compiles. So where is this propagation? I wrote code that ignores unchecked exceptions which was told to be impossible. Please explain me what is wrong with Class.newInstance() regarding the above quotations?
try {
Class<?> c = Class.forName("ConstructorTroubleToo");
// Method propagetes any exception thrown by the constructor
// (including checked exceptions).
Object o = c.newInstance();
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException |
InstantiationException |
IllegalAccessException x
/*IllegalArgumentException |
SecurityException x*/ ) {
x.printStackTrace();
}
Class.newInstance() does indeed propagate any exception thrown by the constructor it calls, checked or unchecked. The propagation is done in a rather underhand way, by calling the method sun.misc.Unsafe.throwException(). This method, which simply throws the exception you give it, is part of the class sun.misc.Unsafe which contains various methods for low-level 'unsafe' operations in Java. This article summarises some of those methods.
In the JDK there is a src.zip file, which contains sources to some standard Java platform classes. In particular, you'll find the source to java.lang.Class within the file java/lang/Class.java in this zip. Open up this file and look at the newInstance() method within it. You'll find that Class.newInstance() actually uses Constructor.newInstance() to create the object.
If a constructor throws an exception, calling the constructor via Constructor.newInstance() will wrap the 'real' exception up in an InvocationTargetException and throw that. However, Class.newInstance() isn't declared to throw an InvocationTargetException, so instead it catches the InvocationTargetException thrown by Constructor.newInstance() and throws the 'real' exception instead, using Unsafe.throwException().
The reason that Class.newInstance() isn't declared to throw InvocationTargetException is because this method dates all the way back to Java 1.0. InvocationTargetException and the rest of the reflection API was introduced to Java in version 1.1. Adding throws InvocationTargetException to Class.newInstance() would have broken backwards compatibility when compiling Java 1.0 code with Java 1.1.
Propagation means that exception just goes out unlike wrapping into InvocationTargetException like reflection methods normally behave.
Actually it's not that impossible to write a code which ignores checked exception. Consider the first case from here:
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
#SuppressWarnings("unchecked")
static <E extends Exception>
void doThrow0(Exception e) throws E {
throw (E) e;
}
}
JVM does not distinguish checked and unchecked exceptions and there are some ways to fool the Java compiler.

Throwing Java exception in JRuby and catching it in Java

I have created my own UI component in Java. It has model and a few of model's methods can throw my exception called ModelException. I want to use this component in JRuby but I can't raise my ModelException:
raise ModelException # it cause TypeError: exception class/object expected
So I tried to create method throwing ModelException in Java and then invoke it in JRuby:
public class ScriptUtils {
private ScriptUtils() {
}
public static void throwModelException(ModelException e)
throws ModelException {
throw e;
}
}
but when I call throwModelException from JRuby I get:
org.jruby.exceptions.RaiseException: Native Exception: 'class app.ui.ModelException'; Message:
; StackTrace: app.ui.ModelException
...
Caused by: app.ui.ModelException
this native exception cannot be handled by Java code.
Any ideas how to throw Java exception in JRuby and catch it in Java?
This is a complete re-write of my original answer as I originally mis-read your question!
You can raise Java exceptions and catch them in JRuby but you need to be a bit careful how you call raise:
raise ModelException
Will cause a type error (as you saw) because to JRuby ModelException looks like a plain constant. Remember that in Ruby class names are constants. You can raise direct subclasses of Ruby Exception like this, e.g.:
raise RuntimeError
But I think such subclasses are a special case. Those that are actually Java classes you need to call with a constructor:
raise ModelException.new
Or whatever constructor/s you have for that class. An instance of ModelException, in JRuby, is a subclass of Exception because JRuby creates it as such, but the Java class itself isn't. All this is assuming that you have imported your ModelException class correctly.
As for your second example, I couldn't replicate that error at all. As long as I created the exception object correctly, as above, it worked and I didn't see any complaints about "Native Exception" at all. So I'm not sure what is happening there, sorry.

Categories