Reputation: 27852
I have been successfully using C3P0 0.9.1.2
with Jetty 8.1.13.v20130916
. In my Jetty server instance, using a Jetty XML configuration file, I bind a C3P0-backed DataSource
to JNDI. Then my web application looks up this DataSource
by name. This has always worked.
I'm currently migrating to C3P0 0.9.5-pre6
and to Jetty 9.1.0.v20131115
.
Since this migration, C3P0 connection pooling doesn't work anymore. I have tried different unpooled and pooled strategies.
Since the migration, the following two unpooled binding strategies work:
<Configure id="Server" class="org.eclipse.jetty.server.Server">
....
<!-- raw mysql connection without C3P0 - THIS WORKS! -->
<New id="jdbc-myds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/myds</Arg>
<Arg>
<New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<Set name="Url">jdbc:mysql://localhost:3306/myds?useUnicode=true&characterEncoding=UTF-8</Set>
<Set name="User">user</Set>
<Set name="Password">pass</Set>
</New>
</Arg>
</New>
</Configure>
<Configure id="Server" class="org.eclipse.jetty.server.Server">
....
<!-- UNPOOLED c3p0 factory - THIS WORKS! -->
<New id="jdbc-myds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/myds</Arg>
<Arg>
<Call class="com.mchange.v2.c3p0.DataSources" name="unpooledDataSource">
<Arg>jdbc:mysql://localhost:3306/myds?useUnicode=true&characterEncoding=UTF-8</Arg>
<Arg>user</Arg>
<Arg>pass</Arg>
</Call>
</Arg>
</New>
</Configure>
Since the migration, the following two pooled binding strategies don't work:
<Configure id="Server" class="org.eclipse.jetty.server.Server">
....
<!-- typical C3P0 pool configuration - THIS DOESN'T WORK FOR ME SINCE MIGRATION -->
<New id="jdbc-myds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/myds</Arg>
<Arg>
<New class="com.mchange.v2.c3p0.ComboPooledDataSource">
<Set name="DriverClass">com.mysql.jdbc.Driver</Set>
<Set name="JdbcUrl">jdbc:mysql://localhost:3306/myds?useUnicode=true&characterEncoding=UTF-8</Set>
<Set name="User">user</Set>
<Set name="Password">password</Set>
</New>
</Arg>
</New>
</Configure>
<Configure id="Server" class="org.eclipse.jetty.server.Server">
....
<!-- wrapping the successfully working C3P0 unpooled DataSource in a pooled DataSource - THIS DOESN'T WORK -->
<New id="jdbc-myds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/myds</Arg>
<Arg>
<Call class="com.mchange.v2.c3p0.DataSources" name="pooledDataSource">
<Arg>
<Call class="com.mchange.v2.c3p0.DataSources" name="unpooledDataSource">
<Arg>jdbc:mysql://localhost:3306/myds?useUnicode=true&characterEncoding=UTF-8</Arg>
<Arg>user</Arg>
<Arg>pass</Arg>
</Call>
</Arg>
</Call>
</Arg>
</New>
</Configure>
In the unsuccessful cases, when visiting the server, the server's HTTP response is a Jetty-served HTTP ERROR: 503, Service Unavailable.
Even though the server-startup logs say that the JNDI resource has been successfully registered, at the moment I am trying to access that JNDI resource by name inside my web application, it doesn't exist anymore: Calling
DataSource myds = new InitialContext().lookup("java:comp/env/jdbc/myds");
throws an InvalidClassException
and a NamingException
:
17:08:33.907 [main] WARN jndi -
java.io.InvalidClassException: com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; local class incompatible: stream classdesc serialVersionUID = -7086951306718003710, local class serialVersionUID = 7806429541739165290
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617) ~[na:1.7.0_45]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622) ~[na:1.7.0_45]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517) ~[na:1.7.0_45]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771) ~[na:1.7.0_45]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) ~[na:1.7.0_45]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) ~[na:1.7.0_45]
at com.mchange.v2.ser.SerializableUtils.deserializeFromByteArray(SerializableUtils.java:132) ~[mchange-commons-java-0.2.6.3.jar:0.2.6.3]
at com.mchange.v2.ser.SerializableUtils.fromByteArray(SerializableUtils.java:111) ~[mchange-commons-java-0.2.6.3.jar:0.2.6.3]
at com.mchange.v2.naming.JavaBeanObjectFactory.createPropertyMap(JavaBeanObjectFactory.java:98) ~[mchange-commons-java-0.2.6.3.jar:0.2.6.3]
at com.mchange.v2.naming.JavaBeanObjectFactory.getObjectInstance(JavaBeanObjectFactory.java:59) ~[mchange-commons-java-0.2.6.3.jar:0.2.6.3]
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321) ~[na:1.7.0_45]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:476) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:518) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:533) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at javax.naming.InitialContext.lookup(InitialContext.java:411) [na:1.7.0_45]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:468) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:551) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:117) [jetty-jndi-9.1.0.v20131115.jar:9.1.0.v20131115]
at javax.naming.InitialContext.lookup(InitialContext.java:411) [na:1.7.0_45]
at com.example.spring.config.MainConfig.dataSource(MainConfig.java:65) [classes/:na]
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d.CGLIB$dataSource$0(<generated>) [cglib-nodep-2.2.2.jar:na]
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d$$FastClassByCGLIB$$554d588d.invoke(<generated>) [cglib-nodep-2.2.2.jar:na]
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [cglib-nodep-2.2.2.jar:na]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d.dataSource(<generated>) [cglib-nodep-2.2.2.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_45]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_45]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1015) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at .............(shortened for brevity)
17:08:33.908 [main] ERROR c.example.spring.config.MainConfig - Couldn't either create InitialContext or couldn't lookup jdbc/myds
javax.naming.NamingException: com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; local class incompatible: stream classdesc serialVersionUID = -7086951306718003710, local class serialVersionUID = 7806429541739165290
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:485)
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:518)
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:533)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:468)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:551)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:117)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at com.example.spring.config.MainConfig.dataSource(MainConfig.java:65)
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d.CGLIB$dataSource$0(<generated>)
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d$$FastClassByCGLIB$$554d588d.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280)
at com.example.spring.config.MainConfig$$EnhancerByCGLIB$$8673699d.dataSource(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at .............(shortened for brevity)
Can anyone see any misconfiguration on my side?
Upvotes: 1
Views: 1152
Reputation: 27852
@Joakim's suggestion helped me locate the problem's source and find a solution. The problem's source didn't have anything to do with Jetty 9.1, instead it stemmed from a Maven dependency library having a transitive dependency on an older C3P0 version 0.9.1.1
:
My web application uses the Quartz scheduler, so my application's pom.xml
included
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.0</version>
</dependency>
org.quartz-scheduler:quartz:2.2.0
has a dependency on c3p0:c3p0:0.9.1.1
.
That old version of C3P0 got into conflict with the newer com.mchange:c3p0:0.9.5-pre6
that I have in my Jetty server instance's lib/etc/
directory.
The solution to my problem is to explicitly exclude Quartz' dependency on that old C3P0 artifact:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
At least for my specific Quartz usage, Quartz still works well.
Upvotes: 1