Lookup von EJB schlägt fehl

Dieses Thema Lookup von EJB schlägt fehl im Forum "Application Tier" wurde erstellt von reNur, 5. Jan. 2012.

Thema: Lookup von EJB schlägt fehl Hallo, folgendes Szenario: Ich erstelle eine Java-Instanz von einem POJO, das das Interface...

  1. Hallo,

    folgendes Szenario:
    Ich erstelle eine Java-Instanz von einem POJO, das das Interface javax.transacion.Synchronization Interface implementiert. Diese Instanz "hänge" ich an eine Transaktion.
    Wird die Transaktion nun durch den Transaktionsmanager beendet, werden ja nacheinander die beforeCompletion und afterCompletion Methoden aufgerufen. Innerhalb dieser Methoden will ich nun ein Stateless EJB aufrufen. Ich mache einen Lookup mit
    Code (Java):

      try {
              ctx = new InitialContext();
          } catch (NamingException e) {
              e.printStackTrace();
              LOG.error("naming exception - can not resolve InitialContext!");
          }

          // get the interface
          try {
            ejb = ( ejbClass ) ctx.lookup("blablabla");
            LOG.debug( "found ejb in JNDI" );
          } catch (NamingException e) {
              e.printStackTrace();
              LOG.error("naming exception at ctx lookup - set ejb to NULL");
              capsEJBapi = null;
          }
     
    Wenn diese Transaktion nun beendet wird, will ich in der Methode afterCompletion(int status) nun eine Methode des EJB aufrufen - also so in der Art
    Code (Java):

    public void afterCompletion(int status)
    {
    ... lookup des ejb ...
    ejb.methode(...)
    ...

    }
    Dies funktioniert auch, falls die Transaktion im Erfolgsfall committed wurde - d.h. der JNDI lookup ist erfolgreich, ich bekomme mein EJB-Interface, kann die Methode aufrufen usw.

    Bei Transaktionen, die durch einen Timeout abgeschlossen werden (also sprich: rollback) wirft genau dieser EJB-Lookup, der vorher noch funktionierte, die Exception:

    Code (Java):
     javax.naming.NamingException: Could not dereference object [Root exception is java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + [email]BaseClassLoader@8bf2e{vfs:///C:/.../jboss-6.0.0.Final/server/all/deploy/transaction-jboss-beans.xml[/email]}]
    Die afterCompletion-Methode wird korrekt aufgerufen, das Synchronisations-Object gibt es also noch.

    Ich verstehe nun nicht ganz, wie das ganze mit den Transaktionen zusammenhängt, insbesondere was es mit der transaction-jboss-beans.xml auf sich hat. Hätte da jemand einen Tipp für mich?
     
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Ich hab ne Vermutung...
    Das ist aber nicht der vollständig stacktrace, kannst du den Posten?
    Besonders interessant sind die Clause-Klauseln.
     
  4. Hallo,


    doe vollständige Exception sieht so aus:


    Code (Java):

    /* hier startet der Transaktionsmanager den Rollback, weil das Transaktions-Timeout abgelaufen ist */
    11:06:02,364 WARN  [com.arjuna.ats.arjuna] ARJUNA-12117 TransactionReaper::check timeout for TX 0:ffffc0a8029a:126a:4f0c0c0f:53 in state  RUN
    11:06:02,389 ERROR [STDERR] javax.naming.NamingException: Could not dereference object [Root exception is java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader(at)1c2f9b7{vfs:///C:/.../jboss-6.0.0.Final/server/all/deploy/transaction-jboss-beans.xml}]

    11:06:02,389 ERROR [STDERR]     at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1508)

    11:06:02,390 ERROR [STDERR]     at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:824)

    11:06:02,390 ERROR [STDERR]     at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)

    11:06:02,390 ERROR [STDERR]     at javax.naming.InitialContext.lookup(Unknown Source)

    11:06:02,391 ERROR [STDERR]     at (lookup-ejb-Methode)(SyncObject.java:91)

    11:06:02,391 ERROR [STDERR]     at SyncObject.afterCompletion(SyncObject.java:39)

    11:06:02,391 ERROR [STDERR]     at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(SynchronizationImple.java:117)

    11:06:02,392 ERROR [STDERR]     at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.afterCompletion(TwoPhaseCoordinator.java:371)

    11:06:02,392 ERROR [STDERR]     at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.cancel(TwoPhaseCoordinator.java:121)

    11:06:02,393 ERROR [STDERR]     at com.arjuna.ats.arjuna.AtomicAction.cancel(AtomicAction.java:212)

    11:06:02,393 ERROR [STDERR]     at com.arjuna.ats.arjuna.coordinator.TransactionReaper.doCancellations(TransactionReaper.java:367)

    11:06:02,393 ERROR [STDERR]     at com.arjuna.ats.internal.arjuna.coordinator.ReaperWorkerThread.run(ReaperWorkerThread.java:79)

    11:06:02,394 ERROR [STDERR] Caused by: java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader(at)1c2f9b7{vfs:///C:/.../jboss-6.0.0.Final/server/all/deploy/transaction-jboss-beans.xml}

    11:06:02,394 ERROR [STDERR]     at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:410)

    11:06:02,394 ERROR [STDERR]     at org.jboss.ejb3.proxy.impl.objectfactory.session.SessionProxyObjectFactory.createProxy(SessionProxyObjectFactory.java:134)

    11:06:02,395 ERROR [STDERR]     at org.jboss.ejb3.proxy.impl.objectfactory.session.stateless.StatelessSessionProxyObjectFactory.getProxy(StatelessSessionProxyObjectFactory.java:79)

    11:06:02,395 ERROR [STDERR]     at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.getObjectInstance(ProxyObjectFactory.java:161)

    11:06:02,396 ERROR [STDERR]     at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)

    11:06:02,396 ERROR [STDERR]     at org.jnp.interfaces.NamingContext.getObjectInstance(NamingContext.java:1483)

    11:06:02,396 ERROR [STDERR]     at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1500)

    11:06:02,397 ERROR [STDERR]     ... 11 more

    11:06:02,398 ERROR [STDERR] Caused by: java.lang.ClassNotFoundException: (EJBapi-Class) from BaseClassLoader(at)1c2f9b7{vfs:///C:/.../jboss-6.0.0.Final/server/all/deploy/transaction-jboss-beans.xml}

    11:06:02,398 ERROR [STDERR]     at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:480)

    11:06:02,398 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)

    11:06:02,398 ERROR [STDERR]     at java.lang.Class.forName0(Native Method)

    11:06:02,399 ERROR [STDERR]     at java.lang.Class.forName(Unknown Source)

    11:06:02,399 ERROR [STDERR]     at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:406)

    11:06:02,399 ERROR [STDERR]     ... 17 more

    11:06:02,400 ERROR [SyncObject] naming exception at ctx lookup - set EJBapi to NULL
    11:06:02,400 ERROR [SyncObject] EJBapi not found at JNDI lookup!
    11:06:02,401 WARN  [com.arjuna.ats.arjuna] ARJUNA-12121 TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,jboss] successfully canceled TX 0:ffffc0a8029a:126a:4f0c0c0f:53
     
    Klassennamen usw. hab ich ersetzt. Der Code läuft aber wie gesagt fehlerfrei, wenn die Transaktion innerhalb der Timeout-Grenzen normal mit einem commit oder rollback abgeschlossen wird - in diesem Fall funktioniert also der JNDI-Lookup. Wäre super wenn du da einen Tipp hättest - ich kanns mir im Moment nicht recht erklären
     
  5. Hat jemand einen Tipp für mich? Der Fehler macht mich wahnsinnig :)
     
  6. Ich vermute mal der Fehler ist folgender:
    Wenn die Transaction commited wird passiert das in dem Kontext, der diese Transaction auch gebraucht hat (also e.g. der in dem eine transaktionale EJB Methode aufgerufen wurde). Das heißt, dass der aktuelle Contextclassloader deine Application kennen muss und damit auch das EJB Interface laden kann, welches du letzendlich aufrufen willst.
    Wird die Transaction durch einen Timeout gekillt passiert das durch einen anderen Thread. Der ist vollkommen unabhängig von deiner Application und daher kennt der Contextclassloader auch dein EJB Interface nicht -> ClassNotFoundException.

    Hast du mal versucht den Lookup beim erstellen deiner Syncklasse zu machen und zu speichern?
     
  7. Hallo,

    ich habe zwar noch nicht sehr viel testen können - aber so wie es aussieht hast du recht! Vielenk Dank, bin echt daran verzweifelt, aber eigentlich ist deine Erklärung ja einleuchtend.
     
  8. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!