英文:
Tomcat9 complaining on class not found for javax.sql.DataSource class
问题
Tomcat9运行在基于Linux的虚拟机上,在部署了一个使用Jdk11编译的WAR文件后,启动时出现以下错误。在Tomcat启动时发生了以下错误。如何解决这个类未找到的异常?是否需要显式添加特定模块java.sql?
我已经尝试在Tomcat启动脚本中添加'--add-modules java.sql',但仍然没有任何区别。还有一个奇怪的现象,当添加'-verbose:module'选项时,它明确显示加载了模块java.sql,但仍然出现NoClassDefFoundError: javax/sql/DataSource错误。
Java版本:
$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)
我们在server.xml中有以下块:
<Resource
name="jdbc/ILOraclePool"
auth="Container"
factory="com.xyz.tomcat.ucp.UcpDataSourceFactory" (这个类扩展了oracle.ucp.jdbc.PoolDataSourceImpl)
type="oracle.ucp.jdbc.PoolDataSource"
description="main DB"
connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
....
/>
如果您需要更多帮助,请告诉我。
英文:
Tomcat9 running on a Linux based VM, startup giving following error, when a Jdk11 compiled war file is deployed in tomcat. On start of tomcat following error occurs. How to resolve this class not found exception. Is specific module java.sql to be added explicitly?
Jul 22, 2020 1:49:45 AM org.apache.catalina.startup.Catalina start
SEVERE: The required Server component failed to start so Tomcat is unable to start.
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[43004]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)
Caused by: java.lang.NoClassDefFoundError: javax/sql/DataSource
at java.base/java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.base/java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:1258)
at java.base/java.lang.System$2.findBootstrapClassOrNull(System.java:2131)
at java.base/jdk.internal.loader.ClassLoaders$BootClassLoader.loadClassOrNull(ClassLoaders.java:118)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:616)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:640)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:616)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:576)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
I have tried adding '--add-modules java.sql' in the tomcat startup script. But still no difference. Also one strange thing is that when '-verbose:module' option is added it clearly shows that module java.sql is loaded, but still ends up with NoClassDefFoundError: javax/sql/DataSource.
find /usr/lib/jvm/adoptopenjdk-11-hotspot -name java.sql.jmod -exec jar tf '{}' \; | grep DataSource
classes/javax/sql/XADataSource.class
classes/javax/sql/ConnectionPoolDataSource.class
classes/javax/sql/DataSource.class
classes/javax/sql/CommonDataSource.class
java version :
$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)
We have following block in server.xml
<Resource
name="jdbc/ILOraclePool"
auth="Container"
factory="com.xyz.tomcat.ucp.UcpDataSourceFactory" (this class extends oracle.ucp.jdbc.PoolDataSourceImpl)
type="oracle.ucp.jdbc.PoolDataSource"
description="main DB"
connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
....
/>
答案1
得分: 2
我认为Tomcat正在使用其他的JVM。请检查一下。
打开位于tomcat9/bin
目录中的catalina.sh文件,并导出JAVA_HOME。
export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-hotspot
英文:
I think tomcat is using some other JVM. Check that.
Open catalina.sh present in tomcat9/bin
directory and export JAVA_HOME.
export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-hotspot
答案2
得分: 2
以下是您要翻译的内容:
对于应用程序服务器中的托管资源,最好将相关库(例如JDBC驱动程序)复制到应用程序服务器特定的libs文件夹(例如Tomcat的catalina/lib,Glassfish的domains/yourdomain/lib等),并在服务器配置文件中注册为主机/域范围或全局范围。
据我所知,将某些JDBC驱动程序打包到部署到Tomcat的可部署war中时可能无法正常工作。而在使用Glassfish、Wildfly等时,我总是使用服务器工具(UI、CLI、Maven插件等)来在服务器配置中注册与JDBC/数据源相关的资源。
更新:我创建了一个新的存储库以演示在Spring Boot中使用此功能,请查看此处。
- oracle-jndi-ds-jar 以Spring Boot jar方式运行。
- oracle-jndi-ds-war 以外部Apache Tomcat中的war方式运行。
两者都包括一个关于Java 11、Oracle XE 18.4.0、JNDI DataSource的IT测试。
mvn verify -Pit
英文:
For the managed resources in the application servers, it is better to copy the related libs(eg. the JDBC drivers) to the application server specific libs folder(eg. the Tomcat's catalina/lib, Glassfish's domains/yourdomain/lib etc) and registered it a host/domain scope or globally in the server config file.
As I know, some JDBC drivers do not work when it is packaged into the deployable war that is deployed into Tomcat. And when using Glassfish, Wildfly, etc., I always used the server tools(UI, CLI, Maven plugin, etc.) to register JDBC/Datasource related resources in the server config.
Update: I created a new repo to demo this usage in Spring Boot, check here.
- oracle-jndi-ds-jar run as Spring Boot jar.
- oracle-jndi-ds-war run as war in an external Apache Tomcat.
Both included an IT test on Java 11, Oracle XE 18.4.0, JNDI DataSource.
mvn verify -Pit
答案3
得分: 2
Ensure that Oracle JDBC jar ojdbc8.jar
、ucp.jar
和 ons.jar
,它们来自同一版本(例如,版本 12.2),都位于 $CATALINA_HOME/lib
中。确保这三个 JAR 文件来自相同的数据库版本。请勿混合使用这些 JAR 的版本。始终尝试使用最新的 JDBC 驱动程序和 UCP 以利用最新的功能和性能改进。
此外,我建议您将工厂类更改为 oracle.ucp.jdbc.PoolDataSourceImpl
。
希望这能解决问题。如果没有帮助,请发布 JNDI 查找代码和 web.xml
中的 DataSource 配置。
英文:
First ensure that Oracle JDBC jar ojdbc8.jar
, ucp.jar
, and ons.jar
from the same version (e.g. version 12.2) are present in $CATALINA_HOME/lib
. Make sure that all three jar files are from the same database version. DO NOT mix the version of these jars. Always, try to use the latest JDBC driver and UCP in order to leverage the latest capabilities and performance improvements.
Also, I recommend you change the factory class to oracle.ucp.jdbc.PoolDataSourceImpl
.
Hopefully, this should resolve the problem. In case it doesn't help, please post the JNDI lookup code and the DataSource configuration in web.xml
.
答案4
得分: 0
你试过将<Resource>移动到context.xml吗?查看Tomcat_Servlet的代码示例。
英文:
Have you tried moving the <Resource> to context.xml ? Check out the Tomcat_Servlet code sample.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论