AbstractMethodError in Spring - java

I'm trying to store data with H2 and hibernate in my Spring project,
and i cant get rid of this:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.AbstractMethodError: ch.qos.logback.classic.Logger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V
at org.apache.commons.logging.impl.SLF4JLocationAwareLog.info(SLF4JLocationAwareLog.java:159)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:187)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
my pom file:
http://pastebin.com/hxXyZi9b
Whats wrong?

There must be version mismatch between your mentioned slf4j dependencies and slf4j lib used spring-core in pom.xml.
If you are using eclipse, you can easily check(by searching) in Depedency Hierarchy tab in pom.xml.

From Spring references documentation:
A common choice might be to bridge Spring to SLF4J, and then provide explicit binding from SLF4J to
Log4J. You need to supply 4 dependencies (and exclude the existing commons-logging): the bridge,
the SLF4J API, the binding to Log4J, and the Log4J implementation itself. In Maven you would do that
like this
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>

Related

log4j 2 migration bridge log4j-1.2-api.jar missing classes

I'm upgrading the version of log4j in our application from log4j 1.2.16 to log4j 2.5. We have many dependencies, so I'm using the log4j 1.x bridge (log4j-1.2-api.jar) that is described in the migration documentation. It describes replacing the old log4j-1.2.16.jar with log4j-1.2-api.jar. Now, however, when a specific dependency is referenced at application start up, I'm getting this message:
java.lang.ClassNotFoundException: org.apache.log4j.SimpleLayout
I see this class in the log4j-1.2.16.jar but not in log4j-1.2-api.jar.
How would I resolve this problem? Here is a portion of my pom for reference:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.5</version>
</dependency>
Can you post the stack trace? Something is referring to a Log4j 1.x specific Layout that won't work in Log4j 2. More than likely something is modifying the logging configuration programmatically. That code will have to be converted to use Log4j 2 configuration and/or APIs.
I had a similar problem. I just copied the java files from the old version, in my case it was FileAppender .

NoSuchMethodError: org/apache/log4j/Logger.setLevel(Lorg/apache/log4j/Level;)

I am using these log4j, slf4j and ch.qos.logback dependencies in my pom.xml of my java project:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
I recently wanted to use an external servlet library and defined that dependency in pom. The init method of this servlet looks like this:
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
....
public class HealthpageServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
private final Logger logger = Logger.getLogger(HealthpageServlet.class.getName());
protected HealthpageService service;
public static final String VERSION = "Healthpage-Version 0.0.4";
public void init() throws ServletException {
logger.setLevel(Level.INFO);
.....
}
My Weblogic Server shows me this exception from the init method, when i start the server:
java.lang.NoSuchMethodError:
org/apache/log4j/Logger.setLevel(Lorg/apache/log4j/Level;)V
When i in eclipse open that HealthpageServlet jar content, it has a log4j-1.2.15 jar inside the WEB-INF/lib folder. But even if i exclude that dependency from pom.xml, i see this exception and my server does not start. What is the problem?
Since the log4j Version (1.2.15) of my external jar was incompatible with the slf4j Version (1.6.4) of my parent project (where logger.setLevel() is not available), i had to update my slf4j to version 1.7.7.
I know it's too late to answer but adding this answer which might help others.
In my case, by trying different configuration I concluded that the log4j and slf4j to work successfully we need to find out the version match. The versions mismatch between spring-mvc and above two dependencies will result in the above error. So try to find out the right version match between 3 dependencies. I tried with below dependencies to get work done.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j13</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

Why can't I use an apache httpcomponents object in spring-boot, even though it is listed in the MVN dependancies?

Spring-boot has the following maven dependencies around org.apache.httpcomponents
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>${httpasyncclient.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${httpclient.version}</version>
</dependency>
However I don't have access to anything org.apache.http related in my codebase unless I add the extra dependency myself.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
Why is this? Isn't this the same as adding a dependency twice?
The artifacts are declared in the dependencyManagement section of the spring-boot-dependencies pom.
Meaning when you inherit from the spring boot starter, you can declare you want to use any of the dependencies managed by it. Notice you don't need to provide a version of the httpclient. This is because Spring has so nicely managed it for you, hence dependencyManagement. So it is not the same thing as declaring it twice.
More info here
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-maven-parent-pom

Can I use Apache HTTPClient without Commons-logging.jar

I'm trying to user Apache HTTPClient in my project. Here does not required any logging for this application. So Can I use HTTPClient without Commons-logging.jar. Otherwise it will be a extra unnecessary burden for my distribution package.
Yes you can. As Hannes suggested - here is my own HttpClient maven setup:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.1</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
Next, since common-logging is indeed a runtime dependency, you will need to define the SLF4J bridge for commons-logging:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
And finally, you will of course need to have a valid SLF4J configuration - here is mine:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.11</version>
</dependency>
Hope this helps.
You can use slf4j with the JCL bridge. This will forward JCL logging to slf4j. Than you add a slf4j adapter like log back or log4j and configure it properly.
When using maven, do not forget to exclude the JCL dependency.
http://www.slf4j.org/legacy.html

How to centralize logging configuration, and use just log4j.properties?

I would like to configure logging in my application with log4j.properties and instruct (somehow) all third-party packages/modules to log through this configuration. Now they log differently and it's a mess: OpenEJB, Hibernate, Apache HttpClient, Jersey, etc. How can I do this? I want to work with log4j only.
Use a framework which can redirect all kinds of logging frameworks to log4j: slf4j.
See "Bridging legacy APIs" for an overview.
[Edit] Maven pom.xml for slf4j:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<!-- The usual exclusions here: javax.mail:mail, oro:oro -->
</dependency>

Categories