我尝试在Java与JNDI结合Tomcat 5.5上的eclipseLink / JPA上建立数据库连接。我已经在web.xml和context.xml中配置了JNDI资源。
db连接可与JNDI一起使用,而无需使用JPA和eclipseLink。在为eclipseLink配置了persistence.xml之后,出现了以下异常。
我不知道如何正确配置persistence.xml以将JNDI数据源用于数据库连接。
例外
WicketMessage: Method onFormSubmitted of interface org.apache.wicket.markup.html.form.IFormSubmitListener targeted at component [MarkupContainer [Component id = loginForm]] threw an exception Root cause: javax.naming.NamingException: This context must be accessed throught a java: URL at org.apache.naming.SelectorContext.parseName(SelectorContext.java:686) at org.apache.naming.SelectorContext.lookup(SelectorContext.java:121) at javax.naming.InitialContext.lookup(InitialContext.java:396) at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110) at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94) at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:16 2) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(Datab aseSessionImpl.java:579) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202) at de.company.myDs.controller.AbstractCrudController.getEntityManager(Unknown Source) at de.company.myDs.controller.UserController.loadUserByName(Unknown Source) at de.company.myDs.controller.LoginController.validateUserLogin(Unknown Source) at de.company.myDs.pages.LoginPage$1.onSubmit(Unknown Source) at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1534) at org.apache.wicket.markup.html.form.Form.process(Form.java:934) at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:896) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182) at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73) at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428) at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479) at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:312) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:637) Complete stack: org.apache.wicket.WicketRuntimeException: Method onFormSubmitted of interface org.apache.wicket.markup.html.form.IFormSubmitListener targeted at component [MarkupContainer [Component id = loginForm]] threw an exception at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:193) at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73) at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428) at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479) java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182) at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73) at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428) at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479) javax.persistence.PersistenceException: Exception [EclipseLink-7060] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException Exception Description: Cannot acquire data source [java:comp/env/jdbc/myDs]. Internal Exception: javax.naming.NamingException: This context must be accessed throught a java: URL at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:408) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202) at de.company.myDs.controller.AbstractCrudController.getEntityManager(Unknown Source) at de.company.myDs.controller.UserController.loadUserByName(Unknown Source) at de.company.myDs.controller.LoginController.validateUserLogin(Unknown Source) at de.company.myDs.pages.LoginPage$1.onSubmit(Unknown Source) at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1534) at org.apache.wicket.markup.html.form.Form.process(Form.java:934) at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:896) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182) at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73) at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428) at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479) Exception [EclipseLink-7060] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException Exception Description: Cannot acquire data source [java:comp/env/jdbc/myDs]. Internal Exception: javax.naming.NamingException: This context must be accessed throught a java: URL at org.eclipse.persistence.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:464) at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:116) at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94) at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:579) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202) at de.company.myDs.controller.AbstractCrudController.getEntityManager(Unknown Source) at de.company.myDs.controller.UserController.loadUserByName(Unknown Source) at de.company.myDs.controller.LoginController.validateUserLogin(Unknown Source) at de.company.myDs.pages.LoginPage$1.onSubmit(Unknown Source) at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1534) at org.apache.wicket.markup.html.form.Form.process(Form.java:934) at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:896) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182) at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73) at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92) at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250) at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329) at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428) at org.apache.wicket.RequestCycle.request(RequestCycle.java:545) at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
web.xml
... <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/myDs</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> ...
context.xml
... <Resource name="jdbc/myDs" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="60000" minEvictableIdleTimeMillis="600000" username="root" password="passwd" maxWait="10000" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/myDs" /> ...
persistence.xml
... <persistence-unit name="myDs" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <non-jta-data-source>java:comp/env/jdbc/myDs</non-jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <class>de.company.myDS.model.User</class> </persistence-unit> ...
只需将类添加JPAEclipseLinkSessionCustomizer到您的项目并配置persistence.xml即可,如下所示:
JPAEclipseLinkSessionCustomizer
<persistence-unit name="yourUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <non-jta-data-source>java:comp/env/jdbc/yourDs</non-jta-data-source> <properties> <property name="eclipselink.session.customizer" value="com.company.yourproject.yourpackage.JPAEclipseLinkSessionCustomizer"/> </properties> </persistence-unit>
您仅需要针对Apache Tomcat的此解决方法。