Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@DataSourceDefinition defined data source can't be used in persistence.xml #510

Closed
arjantijms opened this issue Nov 3, 2015 · 25 comments · Fixed by #575
Closed

@DataSourceDefinition defined data source can't be used in persistence.xml #510

arjantijms opened this issue Nov 3, 2015 · 25 comments · Fixed by #575

Comments

@arjantijms
Copy link
Contributor

Defining a data source from within the application using either @DataSourceDefinition on a class or the data-source element in web.xml, and then using this in persistence.xml will cause a deployment failure.

See https://java.net/jira/browse/GLASSFISH-20944

@smillidge
Copy link
Contributor

This appears to work in CargoTracker OK (at least for the web.xml defined DataSource) is there some specific condition where this fails?

see code referenced below;

https://github.com/smillidge/CargoTracker-J12015/blob/590a8819f9d28246bb3b5ca562352df29bae2674/cargo-monolith/src/main/resources/META-INF/persistence.xml

https://github.com/smillidge/CargoTracker-J12015/blob/master/cargo-monolith/src/main/webapp/WEB-INF/web.xml

@arjantijms
Copy link
Contributor Author

I'll double check and retest with the latest Payara later today. Possibly I used an older version.

@smillidge
Copy link
Contributor

We've not done anything special to fix it! I did notice after I posted the comment CargoTracker uses java:global whereas your examples use java:app.

@arjantijms
Copy link
Contributor Author

java:global is indeed handled distinctively different at places. This also shows up here: https://java.net/jira/browse/GLASSFISH-21447

In that case it's a matter of the context not being set up. Let's see if this indeed makes a difference here as well.

@smillidge
Copy link
Contributor

I don't think we can take the code you've added to the GlassFish JIRA and incorporate it into Payara Server, until it ends up in the GlassFish source tree. We can though take a shot at reimplementing that fix or you can raise a pull request with a signed CLA.

@smillidge smillidge added the PR: TESTS REQUIRED PR Requires Tests to be merged label Nov 3, 2015
@arjantijms
Copy link
Contributor Author

We can though take a shot at reimplementing that fix or you can raise a pull request with a signed CLA.

You mean because I posted it on the GF JIRA it's already licensed?

It would have to be slightly re-implemented anyway, since the code as presented is just a quick POC. For the event being thrown I just took a random existing one that didn't have any further side-effects apart from setting the context. But the real fix should likely introduce a dedicated event, and the try/catch for the validateRequest method should be moved down a little, into the validate() method.

But that fix is of course for JASPIC. The fix for the DataSourceDefinition problem (if it's indeed still a problem) could potentially be done via a fix that's similar in approach but ultimately different code.

At any length I'll ask around for the GF people to incorporate the fix into the GlassFish source tree.

@smillidge
Copy link
Contributor

Not that it is licensed by Oracle just not to us.

@arjantijms
Copy link
Contributor Author

@smillidge

This appears to work in CargoTracker OK (at least for the web.xml defined DataSource) is there some specific condition where this fails?

I took another good look at your example, and I've spotted the main difference that causes the problem.

Your code is using the (semi-external) derby database that ships with GlassFish/Payara. Notice how your pom.xml doesn't have a dependency for derby.

The Java EE 7 samples test includes its own database/jdbc driver; it's embedded in the war (in this case it's h2).

The app or global space appeared to be irrelevant here. With the following in web.xml:

    <data-source>
        <name>java:app/jdbc/MyDS</name>
        <class-name>org.apache.derby.jdbc.EmbeddedDriver</class-name>
        <url>jdbc:derby:/tmp/cargo-tracker-database;create=true</url>
    </data-source>

and no dependency for derby in the pom.xml (hence no derby jar in the war), the test passes. I tested on both GlassFish (4.1.1) and Payara. Even tried an older Payara 4.1 version and there it worked too.

So it's either that the combination {embedded database/driver, data-source in web.xml/annotation, persistence unit} is the problem, OR, it's simply that the h2 embedded database doesn't work with Payara in combination with JPA and/or transactions,

I quickly tried to use another embedded database (went for HSQLDB), but unfortunately HSQLDB seems extraordinary complicated to setup for use with a data-source/jpa, so to rule out h2 as the guilty party I need some more time.

@arjantijms
Copy link
Contributor Author

Turned out HSQLDB wasn't that difficult to setup, just Payara throwing errors.

I added the following data source in web.xml:

 <data-source>
    <name>java:app/MyApp/MyDS</name>
    <class-name>org.hsqldb.jdbc.JDBCDataSource</class-name>
    <url>jdbc:hsqldb:mem:realtime;user=test;password=testx</url>
 </data-source>

The following dependency in pom.xml

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.3.3</version>
</dependency>

And the following in the Arquillian test class:

.addAsLibraries(Maven.resolver()
                .loadPomFromFile("pom.xml")
                .resolve("org.hsqldb:hsqldb")
                .withoutTransitivity()
                .asSingleFile());

To be clear, it's this exact test: https://github.com/javaee-samples/javaee7-samples/tree/master/jpa/datasourcedefinition-webxml-pu

This runs flawlessly on JBoss (WildFly 10.0 rc4) and even on WebLogic (12.2.1), but on Payara and GlassFish results in the following exceptions:

java.lang.IllegalStateException: This web container has not yet been started
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1674)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1633)
    at org.hsqldb.jdbc.JDBCResultSet.getMetaData(Unknown Source)
    at com.sun.gjc.spi.base.ResultSetWrapper.getMetaData(ResultSetWrapper.java:759)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.getColumnNames(DatabaseAccessor.java:1204)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.buildSortedFields(DatabaseAccessor.java:288)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseCall.matchFieldOrder(DatabaseCall.java:648)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:649)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2055)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:306)

And

A system exception occurred during an invocation on EJB TestService, method: public void org.javaee7.jpa.datasourcedefinition_webxml_pu.service.TestService.saveNewEntity()
Warning: javax.ejb.EJBException: Transaction aborted
    at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:729)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy223.saveNewEntity(Unknown Source)
    at org.javaee7.jpa.datasourcedefinition_webxml_pu.service.__EJB31_Generated__TestService__Intf____Bean__.saveNewEntity(Unknown Source)

So there's definitely something fishy (no pun ;)) going on with Payara and GlassFish here.

@smillidge
Copy link
Contributor

At what point is the first exception being thrown, during deployment or when the EJB is called from the second exception?

I didn't realise you could package the driver jar into the war file. Is that part of the spec? I'd always assumed, but never checked, that you dropped the driver somewhere on the server's boot classpath.

@arjantijms
Copy link
Contributor Author

@smillidge

Both exceptions are thrown when the EJB is called. Because of the sheer size of the exceptions being printed it can be a little hard to follow. For some reason pretty much the same exception is printed 7 times. This is the full exception of a single print out:

Warning: java.lang.IllegalStateException: This web container has not yet been started
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1674)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1633)
    at org.hsqldb.jdbc.JDBCResultSet.getMetaData(Unknown Source)
    at com.sun.gjc.spi.base.ResultSetWrapper.getMetaData(ResultSetWrapper.java:759)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.getColumnNames(DatabaseAccessor.java:1204)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.buildSortedFields(DatabaseAccessor.java:288)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseCall.matchFieldOrder(DatabaseCall.java:648)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:649)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2055)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:306)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelect(DatasourceCallQueryMechanism.java:281)
    at org.eclipse.persistence.queries.DataReadQuery.executeNonCursor(DataReadQuery.java:197)
    at org.eclipse.persistence.queries.DataReadQuery.executeDatabaseQuery(DataReadQuery.java:152)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904)
    at org.eclipse.persistence.queries.DataReadQuery.execute(DataReadQuery.java:137)
    at org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:3267)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1790)
    at org.eclipse.persistence.sequencing.QuerySequence.select(QuerySequence.java:309)
    at org.eclipse.persistence.sequencing.QuerySequence.updateAndSelectSequence(QuerySequence.java:254)
    at org.eclipse.persistence.sequencing.StandardSequence.getGeneratedValue(StandardSequence.java:61)
    at org.eclipse.persistence.sequencing.Sequence.getGeneratedValue(Sequence.java:225)
    at org.eclipse.persistence.internal.sequencing.SequencingManager$NoPreallocation_State.getNextValue(SequencingManager.java:696)
    at org.eclipse.persistence.internal.sequencing.SequencingManager.getNextValue(SequencingManager.java:1107)
    at org.eclipse.persistence.internal.sequencing.ClientSessionSequencing.getNextValue(ClientSessionSequencing.java:70)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.assignSequenceNumber(ObjectBuilder.java:362)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.assignSequenceNumber(ObjectBuilder.java:335)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectAndRowWithSequenceNumber(DatabaseQueryMechanism.java:859)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:386)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
    at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904)
    at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:803)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1790)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:227)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:126)
    at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4260)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3168)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:355)
    at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:158)
    at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
    at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:452)
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:854)
    at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:723)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy268.saveNewEntity(Unknown Source)
    at org.javaee7.jpa.datasourcedefinition_webxml_pu.service.__EJB31_Generated__TestService__Intf____Bean__.saveNewEntity(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:434)
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:127)
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
    at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:67)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100)
    at org.javaee7.jpa.datasourcedefinition_webxml_pu.service.TestService$Proxy$_$$_Weld$EnterpriseProxy$.saveNewEntity(Unknown Source)
    at org.javaee7.jpa.datasourcedefinition_webxml_pu.DataSourceDefinitionWebxmlPuTest.insertAndQueryEntity(DataSourceDefinitionWebxmlPuTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.jboss.arquillian.junit.Arquillian$6$1.invoke(Arquillian.java:270)
    at org.jboss.arquillian.container.test.impl.execution.LocalTestExecuter.execute(LocalTestExecuter.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:115)
    at org.jboss.arquillian.core.impl.EventImpl.fire(EventImpl.java:67)
    at org.jboss.arquillian.container.test.impl.execution.ContainerTestExecuter.execute(ContainerTestExecuter.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
    at org.jboss.arquillian.test.impl.TestContextHandler.createTestContext(TestContextHandler.java:89)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createClassContext(TestContextHandler.java:75)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
    at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.test(EventTestRunnerAdaptor.java:111)
    at org.jboss.arquillian.junit.Arquillian$6.evaluate(Arquillian.java:263)
    at org.jboss.arquillian.junit.Arquillian$4.evaluate(Arquillian.java:226)
    at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)
    at org.jboss.arquillian.junit.Arquillian.access$100(Arquillian.java:46)
    at org.jboss.arquillian.junit.Arquillian$5.evaluate(Arquillian.java:240)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.jboss.arquillian.junit.Arquillian$2.evaluate(Arquillian.java:185)
    at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)
    at org.jboss.arquillian.junit.Arquillian.access$100(Arquillian.java:46)
    at org.jboss.arquillian.junit.Arquillian$3.evaluate(Arquillian.java:199)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.jboss.arquillian.junit.Arquillian.run(Arquillian.java:147)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
    at org.jboss.arquillian.junit.container.JUnitTestRunner.execute(JUnitTestRunner.java:65)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.executeTest(ServletTestRunner.java:160)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.execute(ServletTestRunner.java:126)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.doGet(ServletTestRunner.java:90)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)

I did however just notice that the first time after Payara/GlassFish is started and the test is deployed, the following appears in the log:

Warning: java.lang.NullPointerException
    at org.eclipse.persistence.platform.server.ServerPlatformUtils.createServerPlatform(ServerPlatformUtils.java:99)
    at org.eclipse.persistence.sessions.factories.SessionManager.init(SessionManager.java:77)
    at org.eclipse.persistence.sessions.factories.SessionManager.<clinit>(SessionManager.java:71)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.addSessionToGlobalSessionManager(EntityManagerSetupImpl.java:907)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.initSession(EntityManagerSetupImpl.java:2671)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:675)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:205)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getDatabaseSession(EntityManagerFactoryDelegate.java:183)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getDatabaseSession(EntityManagerFactoryImpl.java:528)
    at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactoryImpl(PersistenceProvider.java:385)
    at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:313)
    at org.glassfish.persistence.jpa.PersistenceUnitLoader.loadPU(PersistenceUnitLoader.java:199)
    at org.glassfish.persistence.jpa.PersistenceUnitLoader.<init>(PersistenceUnitLoader.java:107)
    at org.glassfish.persistence.jpa.JPADeployer$1.visitPUD(JPADeployer.java:223)
    at org.glassfish.persistence.jpa.JPADeployer$PersistenceUnitDescriptorIterator.iteratePUDs(JPADeployer.java:510)
    at org.glassfish.persistence.jpa.JPADeployer.createEMFs(JPADeployer.java:230)
    at org.glassfish.persistence.jpa.JPADeployer.prepare(JPADeployer.java:168)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:925)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:434)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:253)
    at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:231)
    at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:275)
    at org.glassfish.admin.rest.resources.TemplateListOfResource.createResource(TemplateListOfResource.java:328)
    at org.glassfish.admin.rest.resources.TemplateListOfResource.post(TemplateListOfResource.java:163)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:309)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:375)
    at org.glassfish.admin.rest.adapter.RestAdapter$2.service(RestAdapter.java:316)
    at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:179)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)

Info: EclipseLink, version: Eclipse Persistence Services - 2.6.1.v20150605-31e8258
Info: /file:/opt/test/glassfish/domains/domain1/applications/72a3993e-4f7f-4e87-9efe-1bf6e3900ff4/WEB-INF/classes/_testPU login successful
Warning: The web application [unknown] registered the JDBC driver [org.hsqldb.jdbc.JDBCDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
[…]
Info: Loading application [72a3993e-4f7f-4e87-9efe-1bf6e3900ff4] at [/72a3993e-4f7f-4e87-9efe-1bf6e3900ff4]
2015-11-19T22:44:16.581+0100|Info: 72a3993e-4f7f-4e87-9efe-1bf6e3900ff4 was successfully deployed in 3,728 milliseconds.

Especially the following stands out:

"The web application [unknown] registered the JDBC driver [org.hsqldb.jdbc.JDBCDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered."

I didn't realise you could package the driver jar into the war file. Is that part of the spec? I'd always assumed, but never checked, that you dropped the driver somewhere on the server's boot classpath.

This was among others discussed in the following issue: https://java.net/jira/browse/JAVAEE_SPEC-7

After some discussion the spec lead said:

"Note also that the defined way to package a JDBC driver with an application
is to package it as a Resource Adapter and include the rar file in the ear file.

Still, it seems like putting the JDBC driver in WEB-INF/lib should also work.

If it doesn't, please file a bug against GlassFish.
We need to see if there's anything in the spec that needs to be clarified in this area."
(emphasis mine)

That bug was filed as: https://java.net/jira/browse/GLASSFISH-19451

It initially looked like to be silently fixed, as it seems an embedded JDBC driver itself can be used since GlassFish 4, but apparently not with JPA.

So basically we have the following 3 issues:

  1. Use @DataSourceDefinition/data-source in web.xml with PU
  2. JDBC driver loaded from WEB-INF/lib
  3. The combination of 1 & 2

I think it's item 3 that is the one that fails now.

@smillidge
Copy link
Contributor

Thanks for the detailed input. This is definitely something we will look to address. I would also like to get all your JASPIC tests to Green on Payara.

@smillidge smillidge added try to reproduce and removed PR: TESTS REQUIRED PR Requires Tests to be merged labels Nov 20, 2015
@smillidge smillidge added this to the Payara Server 4.1.161 milestone Nov 20, 2015
@arjantijms
Copy link
Contributor Author

Thanks for the detailed input. This is definitely something we will look to address.

You're welcome, would be great if this could be fixed.

I would also like to get all your JASPIC tests to Green on Payara.

I've got them all green locally, well, except for the JSF include but that's extremely likely to be more of a JSF issue. As I'm a Mojarra committer I'm going to look at that one soon.

As for the EJB calls that fail; right now I'm trying to see what the best course of action is. I've asked around what it takes to get the fix committed in GlassFish, but I've not yet gotten a definite reply. Alternatively we could see if it can be fixed in Payara and then eventually contribute that back to GlassFish.

@arjantijms
Copy link
Contributor Author

@smillidge

A possible related exception was thrown here: https://travis-ci.org/javaee-samples/javaee7-samples/jobs/93063766

This test case is similar to the one I mentioned above, but it used the XA data source:

<data-source>
     <name>java:app/MyApp/MyDS</name>
     <!-- org.hsqldb.jdbc.JDBCDataSource is non-XA alternative -->
     <class-name>org.hsqldb.jdbc.pool.JDBCXADataSource</class-name>
     <url>jdbc:hsqldb:mem:realtime;user=test;password=testx</url>
 </data-source>

In this case it throws:

Caused by: java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.pool.JDBCXADataSource.getXAConnection(Unknown Source)
    at com.sun.gjc.spi.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java:118)
    ... 144 more
Caused by: org.hsqldb.HsqlException: invalid authorization specification
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    ... 146 more

For the other containers hsqldb doesn't throw this exception, so I assume it's related to how GlassFish sets the username/password.

@smillidge
Copy link
Contributor

The exception below is spurious and has no impact and has been raised with EclipseLink https://bugs.eclipse.org/bugs/show_bug.cgi?id=463629#c10

Warning: java.lang.NullPointerException
    at org.eclipse.persistence.platform.server.ServerPlatformUtils.createServerPlatform(ServerPlatformUtils.java:99)
    at org.eclipse.persistence.sessions.factories.SessionManager.init(SessionManager.java:77)

@smillidge
Copy link
Contributor

Reproduced

java.lang.IllegalStateException: This web container has not yet been started
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1674)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1633)
    at org.hsqldb.jdbc.JDBCResultSet.getMetaData(Unknown Source)

@smillidge
Copy link
Contributor

Done some debugging on this and it looks like the DeploymentClassLoader is being used to try and load driver classes rather than the class loader of the web application. Not sure whether this is a specific H2 Driver issue or an issue with Payara. It looks like the TCCL is not being used to load classes in the driver.

@arjantijms
Copy link
Contributor Author

Not sure whether this is a specific H2 Driver issue or an issue with Payara. It looks like the TCCL is not being used to load classes in the driver.

Okay, that's at least a step closer ;) To rule out H2 specifically is why I also tried with hsqldb.

@arjantijms
Copy link
Contributor Author

One other perhaps related issue; when the above shown data-source configuration is used, but the global namespace is used (e.g. java:global/MyApp/MyDS), the GlassFish does not unbind the data source when the application is undeployed.

When the application is subsequently redeployed, the data source will still exist, and when actually using it will lead to class loader problems at some point, for instance the "This web container has not yet been started" by the WebappClassLoader (See http://grepcode.com/file/repo1.maven.org/maven2/org.glassfish.main.web/war-util/4.1/org/glassfish/web/loader/WebappClassLoader.java#1674)

I checked what some other servers do, and at least JBoss (WildFly 10rc4) does indeed unbind the application provided data source when that application is undeployed.

@smillidge
Copy link
Contributor

Unbinding of the application datasource is now fixed see pull request #565 however I'm not sure this is the cause as it was just the JNDI entry floating around. I think there may be some interplay with JPA as this example deploys fine; https://github.com/payara/Payara-Examples/tree/master/Payara-Micro/datasource-example although it doesn't use JPA. I will extend this example to use JPA as a test case.

@smillidge
Copy link
Contributor

I created an example application using MySQL and can deploy the datasource with a JPA PU no problem on current Payara snapshot. See https://github.com/payara/Payara-Examples/tree/master/Payara-Micro/jpa-datasource-example

@arjantijms
Copy link
Contributor Author

I created an example application using MySQL and can deploy the datasource with a JPA PU no problem on current Payara snapshot.

The example application seems to exercise all the parts that seemingly cause the failure. Did you try running the actual examples from the Java EE 7 samples project on the current Payara snapshot?

If nothing else was fixed, then those "should" still fail.

The differences with the jpa-datasource-example vs Java EE 7 samples are getting smaller though. The main difference is perhaps that the latter uses java:app and h2 + hsqldb.

smillidge pushed a commit to smillidge/Payara that referenced this issue Dec 19, 2015
@smillidge
Copy link
Contributor

This was due to the classloader that initially loaded the Driver classes being a different classloader from the final application classloader. Resulting in a problem whereby when further classes needed to be loaded from the driver an incorrect classloader was used.

The fix is to force the PU loading to use the final application classloader rather than the initial prepare phase deployment classloader.

@smillidge
Copy link
Contributor

Also now added support via #586 for all custom Payara Datasource properties so you can enable connection validation etc. For example in web.xml;

    <data-source>
     <name>java:global/JPAExampleDataSource</name>
     <class-name>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</class-name>
     <server-name>localhost</server-name>
     <port-number>3306</port-number>
     <database-name>mysql</database-name>
     <user>test</user>
     <!-- Example of using a Payara password alias in the datasource definition -->
     <password>test</password>
    <!-- Example of how to use a Payara specific custom connection pool setting -->
     <property>
         <name>fish.payara.slow-query-threshold-in-seconds</name>
         <value>5</value>
     </property>
     <property>
         <name>fish.payara.log-jdbc-calls</name>
         <value>true</value>
     </property>
     <property>
         <name>fish.payara.is-connection-validation-required</name>
         <value>true</value>
     </property>
     <property>
         <name>fish.payara.connection-validation-method</name>
         <value>custom-validation</value>
     </property>
     <property>
         <name>fish.payara.validation-classname</name>
         <value>org.glassfish.api.jdbc.validation.MySQLConnectionValidation</value>
     </property>
    </data-source>

@arjantijms
Copy link
Contributor Author

Also now added support via #586 for all custom Payara Datasource properties

Very nice! This is still something I hope that can be addressed better by the spec somehow. Currently it's a bit of a hit or miss whether the standard {{data-source}} element supports the same properties that the proprietary version of the same element supports.

aubi pushed a commit to aubi/Payara that referenced this issue Jan 3, 2022
 FISH-5824 Added Subresource Integrity for monitoring console
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants