Saltar al contenido

La fuente de datos SpringBoot JNDI arroja java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory

Si te encuentras con algo que te causa duda nos puedes dejar un comentario y trataremos de ayudarte lo más rápido posible.

Solución:

Resolví el problema estableciendo factory attribute en mi Resource Definición. resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");

@Bean
public TomcatEmbeddedServletContainerFactory embeddedServletContainerFactory()
    return new TomcatEmbeddedServletContainerFactory() 

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) 
            tomcat.enableNaming();
            return super.getTomcatEmbeddedServletContainer(tomcat);
        

        @Override
        protected void postProcessContext(Context context) 
            ContextResource resource = new ContextResource();
            resource.setName("jdbc/myDataSource");
            resource.setType(DataSource.class.getName());
            resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
            resource.setProperty("driverClassName", "com.ibm.db2.jcc.DB2Driver");
            resource.setProperty("url", "url");
            resource.setProperty("username", "user");
            resource.setProperty("password", "*****");
            context.getNamingResources().addResource(resource);
        
    ;

Según la documentación de tomcat 8, se supone que infiere automáticamente el tipo de fábrica de db pool mirando DataSource escriba y de alguna manera se predetermina a la fábrica DBCP y esa clase no está en mi ruta de clases.

Supongo que el problema se puede resolver haciendo tomcat-dbcp-** tarros disponibles, pero no estoy seguro de cómo hacerlo con la bota de primavera o incluso si eso es posible con la bota de primavera.

Lo que encuentro extraño es que Spring Boot no incluye las dependencias tomcat-dbcp como parte del POM de inicio, pero usa la fábrica DBCP DataSource como fábrica predeterminada.

El “Starter POM” ya no incluye dependencias jndi reltead, si está utilizando Tomcat / Jetty / etc … con JNDI ahora deberá agregar directamente esta dependencia usted mismo.

Luego configure el JNDI en su archivo application.properties
spring.datasource.jndi-name=java:comp/env/jdbc/yourname

Para su excepción, debe agregar tomcat-dbcp en su archivo pom.xml.

Pero puede verificar las dependencias de su proyecto, si usa spring-boot-starter-jdbc o spring-boot-starter-data-jpa ‘starters’ automáticamente obtendrá una dependencia a “tomcat-jdbc”.

Tienes múltiples opciones:

  • usando la fuente de datos DBCP 2 que es la predeterminada (no desea usar DBCP 1 que está desactualizado y es menos eficiente).
  • utilizando la fuente de datos Tomcat JDBC.
  • utilizando cualquier otra fuente de datos: por ejemplo, HikariCP.

1) Para usar la fuente de datos Apache JDBC, no necesita agregar ninguna dependencia, ya que ya se proporciona en el arrancador Tomcat Spring Boot, pero debe cambiar la clase de fábrica predeterminada a org.apache.tomcat.jdbc.pool.DataSourceFactory para usarlo.
Puedes hacerlo en la declaración de recursos:
resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
Explicaré a continuación dónde agregar esta línea.

2) Para usar la fuente de datos DBCP 2 (que en realidad se espera de forma predeterminada) se requiere una dependencia:


  org.apache.tomcat
  tomcat-dbcp
  8.5.4

Por supuesto, adapte la versión del artefacto de acuerdo con su versión incorporada de Spring Boot Tomcat.

3) Para usar cualquier otra fuente de datos, lo ilustraré con HikariCP, agregue la dependencia requerida si aún no está presente en su configuración (puede ser para HikariCP si confía en los iniciadores de persistencia de Spring Boot) como:


    com.zaxxer
    HikariCP
    3.1.0

y especifique la fábrica que acompaña a la declaración de recursos:

resource.setProperty("factory", "com.zaxxer.hikari.HikariDataSource");

Por ejemplo, con PostgreSQL y una fuente de datos DBCP 2, no especifique ninguna fábrica, ya que es la predeterminada:

    @Override 
    protected void postProcessContext(Context context)             
        ContextResource resource = new ContextResource();
        //...
        context.getNamingResources()
               .addResource(resource);          
    

Aquí las variantes para la fuente de datos Tomcat JDBC y HikariCP.

En postProcessContext() establezca la propiedad de fábrica como se explicó anteriormente para Tomcat JDBC ds:

    @Override 
    protected void postProcessContext(Context context) 
        ContextResource resource = new ContextResource();       
        //...
        resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
        //...
        context.getNamingResources()
               .addResource(resource);          
    
};

y para HikariCP:

    @Override 
    protected void postProcessContext(Context context) 
        ContextResource resource = new ContextResource();       
        //...
        resource.setProperty("factory", "com.zaxxer.hikari.HikariDataSource");
        //...
        context.getNamingResources()
               .addResource(resource);          
    
};

Valoraciones y comentarios

Si te gustó nuestro trabajo, tienes la libertad de dejar una reseña acerca de qué te ha impresionado de este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *