Thanks for the tip Jan! That seemed to get me further than I was... I'm still running into an issue with the Transaction and I believe it's related to the JNDI lookup. According to http://wiki.eclipse.org/Jetty/Feature/JNDI#Configuring_XA_Transactions all that is required is to add a new org.eclipse.jetty.plus.jndi.Transaction passing in com.atomikos.icatch.jta.J2eeUserTransaction (which I found out is for an older version of Atomikos; supposed to use com.atomikos.icatch.jta.UserTransactionImp). It also states that we can then lookup "java:comp/UserTransaction in your web app", but doesn't say how to do this if we are just using a handler. Even so, if that is all that is needed in a webapp, how does Jetty instantiate the com.atomikos.icatch.jta.UserTransactionManager? I found that I had to add a static call to com.atomikos.icatch.jta.UserTransactionManager.init() to my Jetty configuration to get the transaction manager running. I then added a org.eclipse.jetty.plus.jndi.Resource so it could be looked up by OpenJPA in the persistence.xml (below). That all seems to work and I can get data back from queries to the database, but I can't seem to get the org.eclipse.jetty.plus.jndi.Transaction to be recognized. Is there another step that I'm missing to get Jetty to expose the Transaction? Maybe a way to get Jetty to instantiate the transaction manager instead of doing it myself in the jetty configuration?
META-INF/jetty.xml <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <New id="txMgr" class="com.atomikos.icatch.jta.UserTransactionManager"> <Call name="init" /> </New> <New id="txMgrResource" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>java:comp/UserTransactionManager</Arg> <Arg> <Ref id="txMgr" /> </Arg> </New> <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"> <Arg> <New class="com.atomikos.icatch.jta.UserTransactionImp" /> </Arg> </New> <New id="atomikosDS" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>jdbc/myDS</Arg> <Arg> <New id="atomikosDS" class="com.atomikos.jdbc.AtomikosDataSourceBean"> <Set name="minPoolSize">2</Set> <Set name="maxPoolSize">50</Set> <Set name="xaDataSourceClassName">org.h2.jdbcx.JdbcDataSource</Set> <Set name="UniqueResourceName">jdbc/myDS</Set> <Set name="testQuery">SELECT 1 and SELECT 1 FROM DUAL</Set> <Get name="xaProperties"> <Call name="setProperty"> <!-- Must be upper case --> <Arg>URL</Arg> <Arg>jdbc:h2:~/testDB;AUTO_SERVER=TRUE;FILE_LOCK=SOCKET;TRACE_LEVEL_FILE=0;T RACE_LEVEL_SYSTEM_OUT=1</Arg> </Call> <Call name="setProperty"> <Arg>user</Arg> <Arg>sa</Arg> </Call> <Call name="setProperty"> <Arg>password</Arg> <Arg>sa</Arg> </Call> </Get> </New> </Arg> </New> <Ref id='Server'> <Call name="addBean"> <Arg> <New class="org.eclipse.jetty.jndi.DataSourceCloser"> <Arg> <Ref id="atomikosDS" /> </Arg> </New> </Arg> </Call> </Ref> </Configure> META-INF/persistence.xml <?xml version="1.0"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="test-pu" transaction-type="JTA"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <jta-data-source>jdbc/myDS</jta-data-source> <class>com.example.jpa.Message</class> <properties> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> <property name="openjpa.jdbc.JDBCListeners" value="org.ugate.service.UGateJdbcListener"/> <!-- <property name="openjpa.DynamicEnhancementAgent" value="false"/> --> <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72" /> <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=WARN"/> <property name="openjpa.ConnectionFactoryMode" value="managed" /> <property name="openjpa.TransactionMode" value="managed" /> <property name="openjpa.ManagedRuntime" value="jndi(TransactionManagerName=java:comp/UserTransactionManager)" /> </properties> </persistence-unit> </persistence> transactions.properties (root of my class path) com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionSe rviceFactory com.atomikos.icatch.output_dir=${java.io.tmpdir}/atomikos/logs com.atomikos.icatch.log_base_dir=${java.io.tmpdir}/atomikos/logs com.atomikos.icatch.console_log_level=DEBUG -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Jan Bartel Sent: Saturday, April 28, 2012 7:48 PM To: JETTY user mailing list Subject: Re: [jetty-users] Embedded jetty-all 8.1.x JNDI + Atomikos + OpenJPA 2.x Will, java:comp/env is a namespace related to webapps. You don't have a webapp, just a handler. Therefore, put your jndi bindings into the global namespace (rather than the Server instance's namespace), and then look them up from that global namespace. So take out the <Ref id=Server> from the binding of your jndi resource, then look it up with: ctx = new javax.naming.InitialContext(); String configArg = (String) ctx.lookup("jdbc/myDS"); Jan On 27 April 2012 21:33, Will Hoover <[email protected]> wrote: > Hello, > > > > I am trying to configure Jetty (embedded) to use JTA with Atmikos along with > OpenJPA 2.2.0, but I can't seem to get Jetty to recognize my > org.eclipse.jetty.plus.jndi.Resource > > > > Java (startup): > > final Resource serverXml = > Resource.newSystemResource("META-INF/jetty.xml"); > > final XmlConfiguration configuration = new > XmlConfiguration(serverXml.getInputStream()); > > server = (Server) configuration.configure(); > > final SelectChannelConnector defaultConnnector = new > SelectChannelConnector(); > > defaultConnnector.setPort(9080); > > defaultConnnector.setMaxIdleTime(30000); > > defaultConnnector.setRequestHeaderSize(8192); > > server.setConnectors(new Connector[] { defaultConnnector > }); > > server.setHandler(new DefaultHandler()); > > server.setStopAtShutdown(true); > > server.start(); > > server.join(); > > > > public class DefaultHandler extends AbstractHandler { > > private static final Logger log = > LoggerFactory.getLogger(DefaultHandler.class); > > > > public void handle(final String target, final Request baseRequest, > final HttpServletRequest request, > > final HttpServletResponse response) throws IOException, > ServletException { > > javax.naming.Context ctx; > > try { > > ctx = new javax.naming.InitialContext(); > > // Fails here with "javax.naming.NameNotFoundException: > null" > > javax.naming.Context envCtx = (javax.naming.Context) > ctx.lookup("java:comp/env"); > > String configArg = (String) envCtx.lookup("jdbc/myDS"); > > } catch (NamingException e) { > > log.error("No JDBC Resource", e); > > } > > response.setContentType("text/html;charset=utf-8"); > > response.setStatus(HttpServletResponse.SC_OK); > > //baseRequest.setHandled(true); > > response.getWriter().println("<h1>Hello World</h1>"); > > try { > > // Create a new EntityManagerFactory using the System > properties. > > // The "hellojpa" name will be used to configure based on the > > // corresponding name in the META-INF/persistence.xml file > > EntityManagerFactory factory = Persistence. > > createEntityManagerFactory("test-pu", > System.getProperties()); > > > > // Create a new EntityManager from the EntityManagerFactory. > The > > // EntityManager is the main object in the persistence API, > and is > > // used to create, delete, and query objects, as well as > access > > // the current transaction > > EntityManager em = factory.createEntityManager(); > > > > // Begin a new local transaction so that we can persist a new > entity > > em.getTransaction().begin(); > > > > // Create and persist a new Message entity > > em.persist(new Message("Hello Persistence!")); > > > > // Commit the transaction, which will cause the entity to > > // be stored in the database > > em.getTransaction().commit(); > > > > // It is always good practice to close the EntityManager so > that > > // resources are conserved. > > em.close(); > > > > // Create a fresh, new EntityManager > > EntityManager em2 = factory.createEntityManager(); > > > > // Perform a simple query for all the Message entities > > Query q = em2.createQuery("select m from Message m"); > > > > // Go through each of the entities and print out each of their > > // messages, as well as the date on which it was created > > for (Message m : (List<Message>) q.getResultList()) { > > UGateUtil.PLAIN_LOGGER.info(m.getMessage() + " (created > on: " + m.getCreated() + ')'); > > response.getWriter().println("<h3>" + m.getMessage() + " > (created on: " + m.getCreated() + ')' + "</h3>"); > > } > > > > // Again, it is always good to clean up after ourselves > > em2.close(); > > factory.close(); > > } catch (Throwable t) { > > log.error("JPA error: ", t); > > } > > } > > } > > > > META-INF/jetty.xml > > <?xml version="1.0"?> > > <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" > "http://www.eclipse.org/jetty/configure.dtd"> > > <Configure id="Server" class="org.eclipse.jetty.server.Server"> > > <!-- Add a mapping from name in web.xml to the environment --> > > <!-- <New id="map1" class="org.eclipse.jetty.plus.jndi.Link"> --> > > <!-- <Arg> --> > > <!-- <Ref id='Server' /> --> > > <!-- </Arg> --> > > <!-- <Arg>jdbc/myDS</Arg> --> > > <!-- <Arg>jdbc/myDS</Arg> --> > > <!-- </New> --> > > <!-- JTA XADataSource --> > > <New id="myDS" class="org.eclipse.jetty.plus.jndi.Resource"> > > <Arg> > > <Ref id="Server" /> > > </Arg> > > <Arg>jdbc/myDS</Arg> > > <Arg> > > <New class="com.atomikos.jdbc.AtomikosDataSourceBean"> > > <Set name="minPoolSize">2</Set> > > <Set name="maxPoolSize">20</Set> > > <Set > name="xaDataSourceClassName">org.h2.jdbcx.JdbcDataSource</Set> > > <Set name="xaProperties"> > > <New class="java.util.Properties"> > > <Call name="setProperty"> > > <Arg>databaseName</Arg> > > <Arg>testDB</Arg> > > </Call> > > <Call name="setProperty"> > > <Arg>serverName</Arg> > > <Arg>localhost</Arg> > > </Call> > > <Call name="setProperty"> > > <Arg>portNumber</Arg> > > <Arg>5435</Arg> > > </Call> > > <Call name="setProperty"> > > <Arg>user</Arg> > > <Arg>sa</Arg> > > </Call> > > <Call name="setProperty"> > > <Arg>password</Arg> > > <Arg>sa</Arg> > > </Call> > > </New> > > </Set> > > <Set name="UniqueResourceName">jdbc/myDS</Set> > > </New> > > </Arg> > > </New> > > </Configure> > > > > META-INF/persistence.xml > > <?xml version="1.0"?> > > <persistence xmlns="http://java.sun.com/xml/ns/persistence" > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > > xsi:schemaLocation="http://java.sun.com/xml/ns/persistence > > http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" > > version="2.0"> > > <persistence-unit name="test-pu" transaction-type="JTA"> > > > <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> > > <!-- managed DataSource --> > > <jta-data-source>jdbc/myDS</jta-data-source> > > <class>com.example.jpa.Message</class> > > </persistence-unit> > > </persistence> > > > > Exception when looking up "java:comp/env": > > 15:08:45.036 ERROR [qtp144024-32] [o.u.s.w.DefaultServlet:37] No JDBC > Resource > > javax.naming.NameNotFoundException: null > > at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:444) > ~[jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:531) > ~[jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:546) > ~[jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.jav a:112) > ~[jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at javax.naming.InitialContext.lookup(InitialContext.java:411) > ~[na:1.7.0_02] > > at org.ugate.service.web.DefaultServlet.handle(DefaultServlet.java:34) > ~[bin/:na] > > at > org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:1 11) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at org.eclipse.jetty.server.Server.handle(Server.java:351) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpCo nnection.java:454) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpC onnection.java:890) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplet e(AbstractHttpConnection.java:944) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:634) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java :77) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint. java:609) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.j ava:45) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java: 599) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at > org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:5 34) > [jetty-all-8.1.2.v20120308.jar:8.1.2.v20120308] > > at java.lang.Thread.run(Thread.java:722) [na:1.7.0_02] > > > _______________________________________________ > jetty-users mailing list > [email protected] > https://dev.eclipse.org/mailman/listinfo/jetty-users > _______________________________________________ jetty-users mailing list [email protected] https://dev.eclipse.org/mailman/listinfo/jetty-users _______________________________________________ jetty-users mailing list [email protected] https://dev.eclipse.org/mailman/listinfo/jetty-users
