tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Lazar Kirchev (JIRA)" <>
Subject [jira] [Commented] (TOMEE-2058) Problem with persistence in application specifying a context path through sun-web.xml
Date Fri, 16 Jun 2017 07:01:00 GMT


Lazar Kirchev commented on TOMEE-2058:


I found that the problem is that the entities classes get loaded by two different classloaders.

More details:
If there is a sun-web.xml specifying a different context root the application gets deployed
twice in Tomcat, hence the two classloaders. 

First it is deployed with the original context root, and a TomEEWebappClassLoader is created
for it.
All configurations in the Assembler.createApplication() and ConfigurationFactory.configureApplication()
take part here. As part of the deployment in the ConfigurationFactory deployers chain, the
SunConversion deployer is called which detects that the application has a sun-web.xml and
processes it. At this time it changes the contextRoot in the WebModule instance with the context
root from the sun-web.xml. Also during the application creation phase the processing of the
persistence units is performed. The EntityManager implementation is initialized with the descriptors
of the entities. These descriptors are stored in a map, keyed by class objects of the entities'
classes. And these class objects are loaded by the original TomEEWebappClassLoader. 

After that, in TomcatWebAppBuilder.deployWebApps() for each WebApp is checked if it is deployed.
The check is performed in TomcatWebAppBuilder.isAlreadyDeployed() and is based on the context
root. However, as the SunConversion deployer has changed the context root of the WebModule,
the infos structure where the ContextInfo objects of the deployed applications are stored
does not contain an entry for the new context root and that is why the application is deployed
again in Tomcat, and a new TomEEWebappClassLoader gets created. None of the configuration
steps from Assembler.createApplication() are performed upon this deployment. 

When the application is requested through the context root from sun-web.xml, the persistence
fails because the entities classes are loaded with the second TomEEWebappClassLoader, while
the classes in the EntityManager are loaded with the first one and that is why the EntityManager
does not recognize these entities and throws the exception from the description of the issue.

What do you think should be the behavior here?

> Problem with persistence in application specifying a context path through sun-web.xml
> -------------------------------------------------------------------------------------
>                 Key: TOMEE-2058
>                 URL:
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>    Affects Versions: 7.0.3
>            Reporter: Lazar Kirchev
> I am deploying a very simple application with JPA on TomEE Plume. 
> The application uses a sun-web.xml to specify an alternative context root. It defines
one entity (Person) and in a servlet creates an instance of this entity and tries to persist
> If the application is requested through the context root specified in sun-web.xml (http://localhost:8080/Test/TestServlet),
the persisting fails with the following exception:
> {code}
> java.lang.IllegalArgumentException: Object: my.test.entity.Person@1 is not a known Entity
> 	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(
> 	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(
> 	at org.apache.openejb.persistence.JtaEntityManager.persist(
> 	at my.test.TestServlet.doGet(
> 	at javax.servlet.http.HttpServlet.service(
> 	at javax.servlet.http.HttpServlet.service(
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> 	at org.apache.tomcat.websocket.server.WsFilter.doFilter(
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> 	at org.apache.catalina.core.StandardWrapperValve.invoke(
> 	at org.apache.catalina.core.StandardContextValve.invoke(
> 	at org.apache.tomee.catalina.OpenEJBValve.invoke(
> 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(
> 	at org.apache.catalina.core.StandardHostValve.invoke(
> 	at org.apache.catalina.valves.ErrorReportValve.invoke(
> 	at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(
> 	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(
> 	at org.apache.catalina.core.StandardEngineValve.invoke(
> 	at org.apache.catalina.connector.CoyoteAdapter.service(
> 	at org.apache.coyote.http11.Http11Processor.service(
> 	at org.apache.coyote.AbstractProcessorLight.process(
> 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(
> 	at$SocketProcessor.doRun(
> 	at
> 	at java.util.concurrent.ThreadPoolExecutor.runWorker(
> 	at java.util.concurrent.ThreadPoolExecutor$
> 	at org.apache.tomcat.util.threads.TaskThread$
> 	at
> {code}
> On the other hand, if the application is requested through the context path, defined
by the war name (http://localhost:8080/TestPersistence/TestServlet), the entity is successfully
> You can reproduce the problem with the [application|].
For the Data Source resource definition you could use:
> {code}
> <Resource id="myDS" type="DataSource">
>     JdbcDriver org.hsqldb.jdbcDriver
>     JdbcUrl jdbc:hsqldb:file:hsqldb
>     UserName sa
>     Password
> </Resource>
> {code}

This message was sent by Atlassian JIRA

View raw message