El constructor de clases falla al lanzar una excepción en la carga de clases

I have a constructor that fails on the first call to new because an Exception of class javax.persistence.NoResultException being catch in one of the Class' methods.

EDIT: It was not a NoResultException, the NoResultException was the message of the Exception. The stackTrace is below

If I remove the import to javax.persistence.NoResultException and catch just a generic Exception e, the code works.

Mis preguntas son las siguientes:

  1. Why is the code inside a method which hasn't been called is affecting the Constructor? (is not being called in the constructor either)
  2. Why is the ClassLoader throwing an exception which is not supposed to throw? ClassLoader.loadClass() tiros ClassNotFoundException according to JavaDoc.

that catch for javax.persistence.NoResultException as well as the import are old code which managed to survive between versions, I removed it and it's fixed, however I'd like to now the reason behind this.

RASTREO DE LA PILA:

java.lang.NoClassDefFoundError: javax/persistence/NoResultException
    at xxx.xxxxxx.xxxxxxx.xxxx.xxxx.xxxxxxxxxxxx.xxxxxxxxxxxxxxx(ClassB.java)
    ...
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.ClassNotFoundException: javax.persistence.NoResultException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 10 more

Go to the end to see the step by step images of the debugger and the moment it fails

FAILING CODE:

// ClassB.java

import javax.persistence.NoResultException; // NOTICE THE IMPORT

public ClassB{
    private UserInfo user;
    private WebServiceBDelegate port;
    private Connection conn;

    public ClassB (UserInfo user, Connection conn) throws Exception {
        System.out.println("CLASS B CONSTRUCTOR");
        this.user = user;
        this.conn = conn;
        this.port = new WebServiceBService().getForwardingPort();
    }

    public boolean methodB(List<String> list){
        try{
            // Check some stuff on database using this.conn
        } catch(NoResultException nre){         // NOTICE THE CATCH
            String something = getSomething();
        }
        // Get the values to invoke SOAP service using this.conn
        status = port.operationB(values);
        if(status > 0)
            return true;
        return false;
    }
}

CÓDIGO DE TRABAJO:

// ClassB.java

public ClassB{
    private UserInfo user;
    private WebServiceBDelegate port;
    private Connection conn;

    public ClassB (UserInfo user, Connection conn) throws Exception {
        System.out.println("CLASS B CONSTRUCTOR");
        this.user = user;
        this.conn = conn;
        this.port = new WebServiceBService().getForwardingPort();
    }

    public boolean methodB(List<String> list){
        try{
            // Check some stuff on database using this.conn
        } catch(Exception e){         // THIS IS THE CHANGED CATCH
            String something = getSomething();
        }
        // Get the values to invoke SOAP service using this.conn
        status = port.operationB(values);
        if(status > 0)
            return true;
        return false;
    }
}

Here are the step by step images from the debugger when entering INTO the class constructor, to the JVM default ClassLoader and the moment it fails:

STEP INTO when calling new ClassB gets me to loadClassInternal(String) STEP INTO when calling new ClassB gets me to loadClassInternal(String)

STEP INTO loadClassInternal(String), gets me to loadClass(String,boolean) STEP INTO loadClassInternal(String), gets me to loadClass(String,boolean)

STEP INTO loadClass(String,boolean), as far as I can get, now STEP RETURN STEP INTO loadClass(String,boolean), as far as I can get, now STEP RETURN

STEP RETURN gets me to loadClass(String) STEP RETURN gets me to loadClass(String)

STEP OVER gets me to loadClassInternal(String) STEP OVER gets me to loadClassInternal(String)

STEP OVER gives me javax.persistence.NoResultException STEP OVER gives me javax.persistence.NoResultException

STEP OVER TAKES ME BACK TO A FINALLY IN MY CODE AND ENDS EXECUTION

preguntado el 31 de julio de 12 a las 11:07

That's not a duplicate, that one's dealing with the exception that is thrown, this seems to be about a classloading/classpath issue. -

1 Respuestas

  1. The class is loaded into the ClassLoader on first access. The first 'new' statement in your code loads the class into the ClassLoader, which subsequently checks whether it actually has access to all the dependencies of your class (ie. the NoResultException).
  2. You're not making it clear what is being thrown by the ClassLoader, but my guess is it does throw a ClassNotFoundException detailing that the NoResultException is not on your classpath, so it cannot be loaded. That's also why it works when you remove the offending import and catch.

Respondido 31 Jul 12, 12:07

I think you nailed it, which subsequently checks whether it actually has access to all the dependencies of your class, I though that it would only check for dependencies on the moment it was needed. Let me check exactly what is the Exception being thrown, I just assumed it was javax.persistence.NoResultException from picture six - hectorg87

Thank you! That was it! I had to catch a Throwable to be able to check the exception and it took me a while to realize that. It didn't catched it with Exception. I updated my question to show the StackTrace - hectorg87

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.