1 Reply Latest reply on Apr 25, 2014 12:10 PM by wdfink

    Problem with loading MySQL driver class in external library

    kalvatn

      I'm aware this question has probably been asked and (semi-) answered a billion times, at least from what I found when searching, but I've tried all solutions marked as such and I still have had no luck in getting the mysql connector on the classpath. So I'm sorry for asking yet another time. Getting really frustrated of how something so simple can be so complicated.

       

      The case is this; I'm working on a Java EE project, deployed on Jboss 7.1.1.Final using hibernate and mysql for persistence and everything is working just fine.

      I'm also working on a larger Java SE project, which is more or less compiled as a common library for other Java SE projects within the company; so in order to avoid duplicating a bunch of logic found in the library, I want to use this as a dependency in the Java EE project, and doing this is also no problem, the jar is bundled in the .ear and I have no problem calling the classes in the library.

       

      But.. there is some code in the library that accesses databases via standard JDBC code; basically it loads the driver with Class.forName("com.mysql.jdbc.Driver").newInstance(); and then gets the connection to the database via DriverManager.getConnection("jdbc:mysql://host:port/db"). And this is the problem, the classloader can't find the driver class..

       

      I want to stress that the "standard" datasource configuration and everything related to persistence in the Java EE EJBs is working 100%. The mysql driver is installed as a module in modules/com/mysql/main etc.. and this is no problem. Datasources and JPA code is working just fine. I don't want to paste a whole lot of standalone.xml datasource configuration etc. because I feel this is irrelevant. (However if somebody insists this is essential I will try to extract minor portions of this configuration in order to reproduce the problem)

       

      This connector.jar also contains the META-INF/services/java.sql.Driver file with the single line of "com.mysql.jdbc.Driver", from what I've gathered this is required for "as a deployment" method.

      I've tried all the methods of deployment;

      • copied to standalone/deployments (both the connector.jar and my-app.ear deploys just fine, but my-app.ear crashes when it attempts to load the mysql driver).
      • Tried adding com.mysql as a dependency module of modules/org/hibernate/main/module.xml which was suggested in some stackoverflow answer, although I'm fairly certain this is some misguided attempt of getting the "mysql as a module" setup working, which in my case was working just fine already.
      • tried both provided and "non-provided" scopes for maven dependency management.

       

      I'm just completely lost in why JPA with hibernate+mysql recognize the mysql driver because surely there is a similar/identical form of loading the driver class somewhere deep in the persistence api, but when attempting to load the driver "the java SE way" (Class.forName("com.mysql.jdbc.Driver").newInstance()) it fails with a class not found.

       

      TL;DR : current state : have a 100% functional java ee application running on jboss 7.1.1.Final using JPA with hibernate and mysql, no problems with database acess whatsoever.

      problem : Want to use an external library that has java SE jdbc code, which fails due to classloading (stacktrace below)

       

      If someone has a solution I would love if they could create a step by step guide on both java ee project setup and jboss 7 configuration

       

      17:37:31,658 ERROR [com.myapp.package.EJBClass] error loading mysql driver, could not find driver class: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver from [Module "deployment.my-app-1.0.0-SNAPSHOT.ear.my-app-ejb.jar:main" fr
      om Service Module Loader]
              at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:423) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120) [jboss-modules-1.1.1.GA.jar:1.1.1.GA]
              at java.lang.Class.forName0(Native Method) [rt.jar:1.6.0_26]
              at java.lang.Class.forName(Class.java:169) [rt.jar:1.6.0_26]
              at com.betradar.export.businesslogic.config.ConfigManager.postConstruct(ConfigManager.java:66) [xmlexport-ejb.jar:]
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_26]
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_26]
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_26]
              at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_26]
              at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptorFactory$ManagedReferenceLifecycleMethodInterceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptorFactory.java:130) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:112) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:112) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:112) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:112) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.ManagedReferenceInterceptorFactory$ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptorFactory.java:95) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:228) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:333) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ejb3.tx.SingletonLifecycleCMTTxInterceptor.processInvocation(SingletonLifecycleCMTTxInterceptor.java:56) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
              at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:161) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:85) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ejb3.component.singleton.SingletonComponent.getComponentInstance(SingletonComponent.java:116) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ejb3.component.singleton.SingletonComponent.start(SingletonComponent.java:130) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.as.ee.component.ComponentStartService.start(ComponentStartService.java:44) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]
              at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
              at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
              at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_26]
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_26]
              at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_26]
      
        • 1. Re: Problem with loading MySQL driver class in external library
          wdfink

          The driver is loaded by the datasource if you use JPA, so it is decoupled.

          You can use a dependecy to your driver module by adding it to the MANIFEST or use jboss-deployment-structure.xml, see documentation.

           

          But I would prefer to use the already installed datasource and pool. You might use a class in your library to hide the connection details and set this initial with the driver details (JSE) or the JNDI name if you use it inside a JEE container.