[Java/J2EE] UserTransaction gedrag verschil geconstateerd

Pagina: 1
Acties:

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Ik ben een applicatie aan het migreren naar een recente versie van JBoss. Er doet zich een probleem voor bij het starten van een UserTransaction vanuit de client. Onderstaande code werkt op JBoss 3.2.7, maar niet in JBoss 4.0.3SP1. Ik staar me blind op waar het aan ligt.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package re.client;
import java.net.URL;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.transaction.UserTransaction;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class Test {

    private static Logger logger = Logger.getLogger(Test.class);

    public static void main(String[] args) {
        BasicConfigurator.configure(); // initialiseer log4j
        Test test = new Test();
        URL url = test.getClass().getResource("/jndi.properties");
        logger.debug("JNDI props = " + url.toString());
        try {
            Context context = new InitialContext();
            Object o = context.lookup("UserTransaction");
            logger.debug("Object is UserTransaction = " + String.valueOf(o instanceof UserTransaction));
            UserTransaction transaction = (UserTransaction) PortableRemoteObject.narrow(o, UserTransaction.class);
            transaction.begin();
            // doe iets met remote EJBs
            transaction.commit();
        } catch (Exception e) {
            logger.fatal(e);
        }
    }
}


De output van bovenstaande code is als volgt:
0 [main] DEBUG re.client.Test  - JNDI props = file:/C:/Projects/client/src/conf/jndi.properties
984 [main] DEBUG re.client.Test  - Object is UserTransaction = true
1062 [main] FATAL re.client.Test  - javax.transaction.SystemException: java.lang.RuntimeException: UT factory lookup failed


De inhoud van jndi.properties is als volgt:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces


Relevante uitvoer van de JNDI-view service in de JMX-console voor de global namespace:
+- UserTransactionSessionFactory (proxy: $Proxy12 implements interface org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory)
+- UserTransaction (class: org.jboss.tm.usertx.client.ClientUserTransaction)


De volgende dingen heb ik ondernomen om het probleem te verhelpen:
  • Geverifieerd dat jndi.properties in het classpath staat (zie broncode).
  • Geverifieerd dat JBoss een UserTransaction object retourneerd (zie broncode).
  • Bij de overgang naar JBoss 4.0.3SP1 heb ik natuurlijk alle afhankelijkheden in de client verniewd: jboss-j2ee.jar, jnp-client.jar, jboss-client.jar, jboss-jaas.jar, jbosssx-client.jar, jboss-transaction-client.jar en jboss-common-client.jar zijn vervangen door versies die meegeleverd worden met JBoss 4.0.3SP1.
  • In de debugger is geconstateerd dat transaction.begin() verantwoordelijk is voor de exceptie.
  • De exceptie meldt "UT factory lookup failed". Waarschijnlijk is dit een exceptie die optreedt in JBoss? De serverlog van JBoss toont geen excepties.
  • Google leverde niets op.
Suggesties zeer welkom!

[ Voor 4% gewijzigd door ari3 op 30-10-2005 15:56 ]

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ten eerste zie ik dat de "jndi.properties" wel opgezocht wordt, maar niet gebruikt wordt om de initialcontext te initialiseren.

Ten tweede run je dit nu als een standalone testclient? Werkt JTA wel op andere onderdelen in je JBoss 4 configuratie (misschien gewoon een config issue)? Wat gebeurt als je dit vanuit een EJB of een Servlet probeert?

  • ari3
  • Registratie: Augustus 2002
  • Niet online
misfire schreef op zondag 30 oktober 2005 @ 13:34:
Ten eerste zie ik dat de "jndi.properties" wel opgezocht wordt, maar niet gebruikt wordt om de initialcontext te initialiseren.
Jawel, jndi.properties staat in het classpath waar InitialContext() constructor hem zoekt. De initialisatie van de InitialContext is niet het probleem want de UserTransaction wordt immers wel gevonden.
Ten tweede run je dit nu als een standalone testclient? Werkt JTA wel op andere onderdelen in je JBoss 4 configuratie (misschien gewoon een config issue)? Wat gebeurt als je dit vanuit een EJB of een Servlet probeert?
Ja, dit is een standalone testclient. Wanneer ik dezelfde code run vanuit een servlet binnen dezelfde JBoss (4.0.3SP1) instantie werkt het wel, maar dat is niet wat ik nodig heb. Het moet in een standalone client kunnen draaien.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
ari3 schreef op zondag 30 oktober 2005 @ 15:53:
[...]
Jawel, jndi.properties staat in het classpath waar InitialContext() constructor hem zoekt. De initialisatie van de InitialContext is niet het probleem want de UserTransaction wordt immers wel gevonden.
Ah dat is waar ook ja. :) Ik werd even van de wijs gebracht door je debug regel.
[...]
Ja, dit is een standalone testclient. Wanneer ik dezelfde code run vanuit een servlet binnen dezelfde JBoss (4.0.3SP1) instantie werkt het wel, maar dat is niet wat ik nodig heb. Het moet in een standalone client kunnen draaien.
Ik heb even gegoogled op de foutmelding en het probleem kan verschillende oorzaken hebben. Dit stukje code zou wel eens de boosdoener kunnen zijn:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private synchronized void createSession()
   {
      // Destroy any old session.
      if (session != null)
         destroySession();

      try
      {
         // Get a reference to the UT session factory.
         UserTransactionSessionFactory factory;
         Hashtable env = (Hashtable) NamingContextFactory.lastInitialContextEnv.get();
         InitialContext ctx = new InitialContext(env);
         factory = (UserTransactionSessionFactory) ctx.lookup("UserTransactionSessionFactory");
         // Call factory to get a UT session.
         session = factory.newInstance();
      }
      catch (Exception ex)
      {
         throw new RuntimeException("UT factory lookup failed", ex);
      }
   }
In dit geval wordt de echte exception nested meegegeven. Kun je je logger configuratie aanpassen dat ie ook stacktraces en nested exceptions logt? Dan krijg je waarschijnlijk meer info over de foutmelding.

  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
in JBoss kan je in de server/default/conf het bestandje log4j.xml aanpassen zet bij org.jboss het niveau op DEBUG en kijk in je server/default/log naar de uitgebreide foutmeldingen.

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • ari3
  • Registratie: Augustus 2002
  • Niet online
ronaldmathies schreef op maandag 31 oktober 2005 @ 11:38:
in JBoss kan je in de server/default/conf het bestandje log4j.xml aanpassen zet bij org.jboss het niveau op DEBUG en kijk in je server/default/log naar de uitgebreide foutmeldingen.
Heb ik gedaan, maar levert niets op. Ik ben nog eens verder gaan speuren op de fora van JBoss dit alsmede dit gevonden. Dit zijn exact de problemen die ik ook zie.

Ik concludeer dat het ophalen van een UserTransaction implementatie vanuit de client lukt. Echter, wanneer de begin() method aangeroepen wordt moet remote een UserTransactionFactory gevonden worden middels JNDI, maar daar is de (remote) InitalContext niet voor geconfigureerd. Dit is nog niet goed geïmplementeerd in JBoss getuige de antwoorden van Scott Stark (=JBoss engineer) op het forum:
Your going to have to hack the ClientUserTransaction to expose a thread local to which a Properties/Hashtable can be placed for use by the InitialContext. The j2ee appclient naming context factory should be providing a binding for the user transaction as well that would give more control over this, but currently its not.
This code expects that the default ctor of the InitialContext will work. This requires that either the correct jndi.properties file is available to the app classloaders or that the JNDI properties are set as system properties.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand

Pagina: 1