Tomcat9 抱怨找不到 javax.sql.DataSource 类的类。

huangapple go评论156阅读模式
英文:

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 &#39;{}&#39; \; | 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 &quot;11.0.7&quot; 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

&lt;Resource
	name=&quot;jdbc/ILOraclePool&quot;
	auth=&quot;Container&quot;
	factory=&quot;com.xyz.tomcat.ucp.UcpDataSourceFactory&quot; (this class extends oracle.ucp.jdbc.PoolDataSourceImpl)
	type=&quot;oracle.ucp.jdbc.PoolDataSource&quot;
	description=&quot;main DB&quot;
	connectionFactoryClassName=&quot;oracle.jdbc.pool.OracleDataSource&quot;
	....
/&gt;

答案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中使用此功能,请查看此处

两者都包括一个关于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.

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.jarucp.jarons.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.

huangapple
  • 本文由 发表于 2020年7月22日 22:03:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63036098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定