Changing logging level of spark in Scala using log4j2 - scala

I am using Scala to do some Spark job (my spark version is 2.1 running on Amazon AWS)
To be able to use log4j2 I have added this to my POM.XML
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api-scala_2.11</artifactId>
<version>11.0</version>
</dependency>
<!--log4j-api and log4j-core versions should be 2.8.2 it's not working for higher version at this moment-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
And I have this log4j2.xml in my resources
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}t [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
I want to change the level of the log for Spark to WARN because of this issue, but since spark using log4j (version 1 ) I can not control it in my log4j2.xml file. Any workaround?
I have also followed other solution by adding following code but still, it didn't work
import org.apache.log4j.{Level, LogManager, Logger}
val ss = SparkSession.builder().getOrCreate()
ss.sparkContext.setLogLevel("WARN")
LogManager.getLogger("org").setLevel(Level.WARN)
LogManager.getLogger("akka").setLevel(Level.WARN)
Logger.getLogger("org").setLevel(Level.WARN)
Logger.getLogger("akka").setLevel(Level.WARN)
Logger.getRootLogger().setLevel(Level.WARN)

Related

Hello, I was wondering is there any way for use Tinylog with app which is requiring Log4J2 implementation. (adapter or something)

I was wondering is there any way for use Tinylog with app which is requiring Log4J2 implementation. (adapter or something)
If I understand your question correctly, you want to use the tinylog 2 API with an Apache Log4j 2 logging back-end. You can do that by using JBoss logging as an adapter between both.
Required dependencies:
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-api</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-jboss</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.0</version>
</dependency>
Example Application:
import org.apache.logging.log4j.LogManager;
import org.tinylog.Logger;
public class Application {
public static void main(String[] args) {
Logger.info("Greetings from tinylog!");
LogManager.getLogger().info("Greetings from Apache Log4j 2!");
}
}
Example Log4j configuration (nothing special):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %logger %level: %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="ConsoleAppender" />
</Root>
</Loggers>
</Configuration>
Output on my computer:
21:01:27.367 [main] Application INFO: Greetings from tinylog!
21:01:27.368 [main] Application INFO: Greetings from Apache Log4j 2!

Problem with project dependencies and logs in scala

I have two scala maven projects, we will call them "A" and "B".
"A" project is a dependency of "B". I use "A" like a library; "A" is included in dependencies in "B" pom.xml file.
And I use org.apache.logging.log4j.scala.Logging library to see the logs with configuration files (xml extension) like this in the src/main/resources folder in the both projects:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} %L - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="group.id.projectname" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="warn">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
When I run my tests I see perfectly the result of the logs in my IDE console.
But, when I run my project in a cluster in AWS I can see error and warn logs of the project "B" only.
In project "B":
logger.error("message") -> yes
logger.warn("message") -> yes
logger.info("message") -> no
logger.trace("message") -> no
In project "A": I can see all in IDE but nothing in a cluster
I have tried some things:
Remove:
<Logger name="group.id.projectA" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
Add dependency exclusion in pom file :
<dependency>
<groupId>group.id</groupId>
<artifactId>projectB</artifactId>
<version>${projectB.version}</version>
<exclusions>
<exclusion>
<artifactId>log4j-api-scala_${scala.tools.version}</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
</exclusions>
</dependency>
Change additivity="false" to additivity="true" in log4j2.xml file in "B" project
Change additivity="false" to additivity="true" in log4j2.xml file in "B" project and "A" project
But no test has worked.
Any ideas? Thanks in advance!!

Getting ClassCastException when trying to cast Logger object to my own wrapper logger

I am trying write a wrapper logger class by extending Logger, which will log class name , method name, message and error/exception details.
Getting exception in below line
ILogger logger =
(CustomLogger)org.apache.logging.log4j.LogManager.getLogger(name);
Using below XML, sometimes it's taking SLF4J logger too and getting SLF4j binding exceptions too.
My pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.Logger</groupId>
<artifactId>WrapperLogger</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>WrapperLogger</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.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-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
===================================================================
log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<!-- Console Appender -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %M,%C,
%-5level %logger{36} - %msg%n" />
</Console>
<!-- File Appender -->
<File name="File" fileName="d:/app.log">
<PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level
%logger{36} - %msg%n" />
</File>
</Appenders>
<Loggers>
<!-- Log everything in custom package -->
<Logger name="com.boraji.tutorial.springboot" level="debug" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Logger>
<!-- Log everything in Spring Boot -->
<Logger name="org.springframework.boot" level="debug" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Logger>
<!-- Log everything in Spring Core -->
<Logger name="org.springframework.core" level="debug" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Logger>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Root>
To remove slf4j binding exceptions, you should probably remove spring-boot-starter-logging dependency from your pom.xml.
Actually, this dependency is already added by spring-boot-starter artificat so you need to exclude it like below -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

Setting up log4j2 with Scala project

I am using Maven for my Scala project and I am trying to use log4j2.
At First, I just added
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api-scala_2.11</artifactId>
<version>11.0</version>
</dependency>
To list of my dependency and add the following XML file to my resources folder. I have created the resources folder alongside scala folder both in main and test.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{0} %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.simpleproject" level="debug" additivity="false">
<AppenderRef ref="console"/>
</Logger>
<Root level="error">
<AppenderRef ref="console"/>
</Root>
</Loggers>
</Configuration>
Yet it didn't work a produce this error :
ERROR StatusLogger Log4j2 could not find a logging implementation.
Please add log4j-core to the classpath. Using SimpleLogger to log to
the console...
Even I tried properties file instead of XML but still no luck:
name=PropertiesConfig
property.filename = logs
appenders = console, file
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.file.type = File
appender.file.name = LOGFILE
appender.file.fileName=${filename}/full-scala.log
appender.file.layout.type=PatternLayout
appender.file.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
loggers=file
logger.file.name=guru.springframework.blog.log4j2properties
logger.file.level = debug
logger.file.appenderRefs = file
logger.file.appenderRef.file.ref = LOGFILE
rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT
Then I find this post, so I update my pom.xml to have this 3 dependancy:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api-scala_2.11</artifactId>
<version>11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
But Still I get the same error and it doesn't show the log the way I want or the level of the log I want (Only shows level above Error)
According to Apache page of this project log4j-api and log4j-core versions should be 2.8.2 (Version 2.8.2 worked for this case)
According to GitHub page of this project log4j-api and log4j-core versions should be 2.11.0

HTTP 500 - Cannot create JDBC driver of class '' for connect URL 'null'

I have been searching to fix that problem for 3 days reading forums... Then I decided to ask for some help. Nedless to say that your help would be highly appreciated :-)
I created a jndi resource for the mysql connexion in Tomcat context.xml instance in Eclipse
My web app works fine when I start the server from eclipse. It doesn't work fine when I start the web app from eclipse 'Run configurations' with that goals : clean tomcat7:run. My aim is to delegate the build, deploy, start server to maven from eclipse.
I've put the mysql-connector-java-5.1.27.jar in Tomcat_Home/lib.
I don't want to put the datasource configuration in the app (no META-INF....) as one goal of jndi is to place the datasource info out of the app.
Thank you for reading and for the time you'll spend to find a solution.
Technical specifications
eclipse : juno release2
spring tool suite : 3.4
wtp
m2e : 1.4
maven : 3.0.2
jdk : 1.6.21
tomcat : 7.0.25
mysql : 5.6.14
stacktrace
type Exception report
message Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:927)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:573)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:662)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:702)
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:178)
com.marc.springmvc3.dao.PersonDAO.getPersonById(PersonDAO.java:26)
com.marc.springmvc3.service.PersonService.getAllPersons(PersonService.java:18)
com.marc.springmvc3.mvc.PersonController.getListOfPerson(PersonController.java:33)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:123)
org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:97)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:723)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:573)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:662)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:702)
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:178)
com.marc.springmvc3.dao.PersonDAO.getPersonById(PersonDAO.java:26)
com.marc.springmvc3.service.PersonService.getAllPersons(PersonService.java:18)
com.marc.springmvc3.mvc.PersonController.getListOfPerson(PersonController.java:33)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:123)
org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:97)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:723)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
java.lang.NullPointerException
sun.jdbc.odbc.JdbcOdbcDriver.getProtocol(JdbcOdbcDriver.java:507)
sun.jdbc.odbc.JdbcOdbcDriver.knownURL(JdbcOdbcDriver.java:476)
sun.jdbc.odbc.JdbcOdbcDriver.acceptsURL(JdbcOdbcDriver.java:307)
java.sql.DriverManager.getDriver(DriverManager.java:253)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:573)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:662)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:702)
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:178)
com.marc.springmvc3.dao.PersonDAO.getPersonById(PersonDAO.java:26)
com.marc.springmvc3.service.PersonService.getAllPersons(PersonService.java:18)
com.marc.springmvc3.mvc.PersonController.getListOfPerson(PersonController.java:33)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:123)
org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:97)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:723)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.47 logs.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.marc</groupId>
<artifactId>spring-mvc-3</artifactId>
<name>spring-mvc-3</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.2.0.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.1</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>runtime</scope>
</dependency>
<!-- #Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- JSR 303 with Hibernate Validator -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
<!-- MYSQL driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.27</version>
</dependency>
<!-- JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>20030825.184428</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>spring-mvc-3</finalName>
<plugins>
<!-- Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://127.0.0.1:8080/manager/text</url>
<server>TomcatServer</server>
<path>/${project.build.finalName}</path>
<port>8080</port>
<charset>UTF-8</charset>
<finalName>${project.build.finalName}</finalName>
<username>ssss</username>
<password>dddddddddd</password>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.27</version>
</dependency>
</dependencies>
</plugin>
<!-- Maven compiler plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
</plugins>
</build>
Servers/tomcat-config/tomcat-users.xml (in Eclipse)
<role rolename="admin"/>
<user username="ssss" password="dddddddddd" roles="admin"/>
web.xml
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- database jndi reference -->
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/TestDB"
expected-type="javax.sql.DataSource"
resource-ref="true"/>
<bean id="personDao" class="com.marc.springmvc3.dao.PersonDAO">
<property name="dataSource" ref="dataSource"/>
</bean>
tomcat context.xml (in eclipse)
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->
<Resource name="jdbc/TestDB"
username="xxx"
password="xxxxxxxx"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mytest"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
initialSize="1"/>
<!-- <ResourceLink name="jdbc/TestDB"
global="jdbc/TestDB"
type="javax.sql.DataSource"/> -->
</Context>
I think your tomcat installation is not using your context.xml. Please create fresh tomcat, configure context.xml and libs and run Tomcat directly from system (without Eclipse etc).
Question was updated, answer below is obsolete :/
The important part is:
Cannot create JDBC driver of class '' for connect URL 'null'
Your driver class is null and connection URL is null.
Application configuration requires configured resource jdbc/TestDB on server:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/TestDB"
expected-type="javax.sql.DataSource"
resource-ref="true"/>
But your Tomcat configuration Servers/tomcat-config/context.xml is wrong. It looks like spring application configuration.
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
...
Standard Tomcat context.xml looks like this:
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
username="user" password="pass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testDB?characterEncoding=utf8" maxActive="8"/>
</Context>
I've eventually found out the solution and I'll share it with those who are encountering the same problem.
Create the META-INF folder under src/main/webapp as WEB-INF sibling
Move the Tomcat-config/context.xml file to the META-INF folder. You'll see in the pom.xml that this file is not going to be part of the WAR file.
META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource name="jdbc/TestDB"
username="xxxx"
password="xxxxxxxxxx"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/TestDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
initialSize="1"/>
</Context>
Adapt the pom.xml
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://127.0.0.1:8080/manager/text</url>
<server>TomcatServer</server> <!-- user + password defined in the Maven/conf/settings.xml-->
<path>/${project.build.finalName}</path>
<port>8080</port>
<charset>UTF-8</charset>
<finalName>${project.build.finalName}</finalName>
<contextFile>${project.basedir}/src/main/webapp/META-INF/context.xml</contextFile> <!--The path of the Tomcat context XML file. This is not used for war deployment mode.-->
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <!-- driver mysql -->
<version>5.1.27</version>
</dependency>
</dependencies>
</plugin>
MAVEN_HOME/conf/settings.xml
The id is referenced in the pom.xml. The username and the password are declared in the tomcat-users.xml
<server>
<id>TomcatServer</id>
<username>xxxxx</username>
<password>xxxxxxxxx</password>
</server>
Eclipse / Run - Run configurations ...
create new launch configuration
Base direrctory ${workspace_loc:/your project name}
Goals clean tomcat7:run
Apply
Run
Next time you can click on the arrow near the Run As... button in the ToolBar and select the configuration you want to run. The Stop and Relaunch buttons are very useful.
I am using Eclipse STS 3.9.3, tomcat 8.5 and Spring Boot 2.0.0.RELEASE
I spent my entire morning about this problem.
So, I did a lot of things to solve:
Remove jdbc dependence from my pom.
<!-- dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency-->
Declaration resource TOMCAT_HOME/CONF/server.xml whit factory:
<GlobalNamingResources>
...
<Resource name="jdbc/postgres_jndi"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://xxx.xxx.xx.xxx:5432/db"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
removeAbandonedOnBorrow="true"
removeAbandonedOnMaintenance="true"
timeBetweenEvictionRunsMillis="10000"
removeAbandonedTimeout="60"
logAbandoned="true"
username="xxx"
password="xxxxxx"
maxTotal="20"
maxIdle="10"
maxWaitMillis="-1"/>
...
</GlobalNamingResources>
I realized that I was using Eclipse STS. The tomcat resource on server.xml only works after I put the resource declaration in server.xml inside of "Tomcat v8.5 Server at localhost-config" folder in my Server project. Did not work on TOMCAT_HOME/conf folder in server.xml file.
Change my application.yml to:
spring:
datasource:
platform: postgres
jndi-name: java:comp/env/jdbc/postgres_jndi
type: javax.sql.DataSource
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: validate
database-platform: org.hibernate.dialect.PostgreSQL9Dialect
database: POSTGRESQL
show-sql: true
#Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented.
properties:
hibernate:
temp:
use_jdbc_metadata_defaults: false
A application.properties will be like:
spring.datasource.platform= postgres
spring.datasource.jndi-name= java:comp/env/jdbc/postgres_jndi
spring.datasource.type= javax.sql.DataSource
spring.datasource.driver-class-name= org.postgresql.Driver
spring.jpa.hibernate.ddl-auto= validate
spring.jpa.hibernatedatabase-platform= org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.database= POSTGRESQL
spring.jpa.show-sql= true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
Define a context.xml file in src/main/webapp/META-INF/context.xml with definition:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/myapp">
<ResourceLink global="jdbc/postgres_jndi" name="jdbc/postgres_jni" type="javax.sql.DataSource"/>
</Context>
Put the file postgresql-42.2.2.jar in the TOMCAT_HOME/lib