2017-02-04 2 views
2

Я пытаюсь добавить внешнюю банку во время выполнения, а затем использовать эту банку для подключения к базе данных (вместо того, чтобы добавьте много драйверов в pom, цель состоит в том, чтобы предоставить пользователю возможность загружать любую флешку драйвера во время выполнения). Я использую проект загрузки весны, и я пытаюсь использовать весенние ботинки DataSourceBuilder для создания источника данных.Добавление драйвера JDBC во время выполнения - вызвано: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

Ответы и предложения в Loading JDBC Driver at Runtime и Loading jars at runtime не похоже на работу на следующий код:

@Component 
public class DriverLoader { 

    private static final String URL = "jdbc:mysql://localhost:3306/sakila?useSSL=false"; 
    private static final String USER = "root"; 
    private static final String ADMIN = "admin"; 
    private static final String DRIVER_JAR = "C:\\Users\\Sander\\Downloads\\mysql-connector-java-5.1.40.jar"; 

    @PostConstruct 
    private void loadDriver() throws Exception { 
     File file = new File(DRIVER_JAR); 
     if (file != null) { 
      URLClassLoader URLClassLoader = new URLClassLoader(new URL[] {file.toURI().toURL()}, System.class.getClassLoader()); 
      String driverName = DatabaseDriver.fromJdbcUrl(URL).getDriverClassName(); 
      System.out.println(driverName); 

      // lets try to load the class 
      Class<?> driverClass = URLClassLoader.loadClass(driverName); 
      Driver actualDriver = (Driver) driverClass.newInstance(); 
      URLClassLoader.close(); 

      // Throws: Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.StringUtils 
      /*Properties properties = new Properties(); 
      properties.put("user", USER); 
      properties.put("password", ADMIN); 
      Connection con = actualDriver.connect(URL, properties);*/   

      DataSource dataSource = createNewDataSource(URL, USER, ADMIN); 

      if (dataSource != null) { 
       // lets try to connect 
       // Throws: Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 
       dataSource.getConnection().isValid(1); 
      }   
     }  
    } 

    public DataSource createNewDataSource(String url, String username, String password) { 
     return DataSourceBuilder 
       .create() 
       .url(url)  
       .username(username) 
       .password(password) 
       .build(); 
    }  
} 

Отрывок из ПОМ Я использую:

<parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.5.1.RELEASE</version> 
     <relativePath/> <!-- lookup parent from repository --> 
    </parent> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
     <java.version>1.8</java.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-jdbc</artifactId>   
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 

Как я могу использовать DataSourceBuilder успешно установить соединение с источником данных, учитывая, что файл jar был добавлен во время выполнения?

Полный трассировки стека:

2017-02-04 20:13:22.201 ERROR 12528 --- [   main] o.a.tomcat.jdbc.pool.ConnectionPool  : Unable to create initial connections of pool. 

java.sql.SQLException: Unable to load class: com.mysql.jdbc.Driver from ClassLoader:[email protected];ClassLoader:[email protected] 
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:283) ~[tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:732) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:664) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:479) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.11.jar:na] 
    at nl.mierasmade.driver.DriverLoader.loadDriver(DriverLoader.java:54) [classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_112] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_112] 
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_112] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) [spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) [spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) [spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE] 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE] 
    at nl.mierasmade.JdbcRuntimeDriverApplication.main(JdbcRuntimeDriverApplication.java:10) [classes/:na] 
Caused by: java.lang.ClassNotFoundException: Unable to load class: com.mysql.jdbc.Driver from ClassLoader:[email protected];ClassLoader:[email protected] 
    at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:56) ~[tomcat-jdbc-8.5.11.jar:na] 
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:271) ~[tomcat-jdbc-8.5.11.jar:na] 
    ... 33 common frames omitted 
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 
    at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_112] 
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_112] 
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_112] 
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_112] 
    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_112] 
    at java.lang.Class.forName(Unknown Source) ~[na:1.8.0_112] 
    at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:38) ~[tomcat-jdbc-8.5.11.jar:na] 
    ... 34 common frames omitted 
+0

Постарайтесь не близко URLClassLoader, что происходит? – cybersoft

+0

Такое же исключение. В документации указано: «Кроме того, все классы или ресурсы, которые уже загружены, все еще доступны», поэтому закрытие не должно быть проблемой. –

+0

Не все классы могут быть загружены из этого кувшина, так закрытия также может быть причиной ... Странно, что загрузка класса и создания нового экземпляра в порядке, но не после того, как близко – cybersoft

ответ

2

я смог работать так:

@Bean 
    public DataSource dynamicDataSource() { 
    ClassLoader classLoader = new URLClassLoader(new URL[]{new URL("file:///C:/Users/xxxx/Desktop/h2-1.4.193.jar")}, Thread.currentThread().getContextClassLoader()); 
    Thread.currentThread().setContextClassLoader(classLoader); 
    DataSource dataSource = DataSourceBuilder.create().url('jdbc:h2:mem:test;DB_CLOSE_DELAY=-1').build(); 
    dataSource.getConnection().isValid(10); 
    return dataSource; 
    } 
0

попробовать this.getClass().getClassLoader() или Thread.getContextClassLoader() вместо того, чтобы использовать загрузчик классов системы. См this раздел Е.5.2 Система ClassLoader

+0

Оба 'this.getClass(). GetClassLoader() 'as' Thread.currentThread(). getContextClassLoader() 'бросает исключение класса, не найденное. Спасибо за ссылку. –

Смежные вопросы