views:

642

answers:

6

I have a Java EE 6 Wicket application deployed with maven using IntelliJ IDEA 9.0.3 on glassfish v3.0.1. I use slf4j-log4j12-1.5.6 with slf4j-api-1.5.8 and log4j-1.2.16 for logging.

It was previously working fine when I deployed through netbeans or eclipse, however when I deploy with IntelliJ IDEA my log4j.properties file is ignored and glassfish's logging handles my log messages. I do not think IDEA has anything to do with it, something else must have changed I just can't figure out what.

I have verified that my log4j.properties file is in my WEB-INF/classes directory and the slf4j/log4j jars are in the WEB-INF/lib directory of my war. Is there some sort of configuration I am missing to make this work?

thanks.

edit: Updated with more info, posted pom dependencies.

Here is the relevant section from my pom.xml:

    <!-- Guava -->

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>r05</version>
    </dependency>

    <!-- Test -->

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>3.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Java EE 6 -->

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>bean-validator</artifactId>
        <version>3.0-JBoss-4.0.0.Beta3</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- Wicket -->

    <dependency>
        <groupId>org.apache.wicket</groupId>
        <artifactId>wicket</artifactId>
        <version>1.4.9</version>
    </dependency>
    <dependency>
        <groupId>org.apache.wicket</groupId>
        <artifactId>wicket-auth-roles</artifactId>
        <version>1.4.9</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.weld</groupId>
        <artifactId>weld-wicket</artifactId>
        <version>1.0.1-Final</version>
    </dependency>

    <!-- Hibernate -->

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.5.1-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.5.1-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-commons-annotations</artifactId>
        <version>3.2.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.5.1-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>3.5.1-Final</version>
    </dependency>


    <!-- Database -->

    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>8.4-701.jdbc4</version>
    </dependency>


    <!-- Logging -->

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>

</dependencies>
A: 

The two most likely things that spring to mind are:

  1. make sure the log4j.properties file is in WEB-INF/classes of the deployment. I assume you mean it is in your WEB-INF/classes in your codebase, but have you confirmed this is the case in the war that sent to glassfish
  2. make sure your log4j.jar is in your deployed WEB-INF/lib

Since it's working in some deployment scenarios, I suspect your war packaging when running via Maven is the problem. The above points should help you confirm this.

jowierun
jowierun - I have checked the war, log4j.properties is indeed in WEB-INF/classes. I don't have a log4j.jar, i have slf4j-log4j12.jar. The odd thing is, this exact configuration worked properly in netbeans and eclipse before we switched to IDEA.
kgrad
When I want reproducibility, I run maven from the command line and manually deploy the WAR files. Perhaps you should try this, and also compare WAR files created this way with WAR files created/deployed by the respective IDEs.
Stephen C
@Stephen C - I deployed the war via the command line and checked server.log and still don't see log4j working properly nor is my file appender working.
kgrad
@kgrad - just in case you haven't, have you looked for any errors in the startup output? I have seen errors hiding in the masses of app server startup in the past. Also, it might be worth dumping the classpath out from a class or JSP in your deployment - that should confirm what Jars you have access to.
jowierun
@kgrad - did you check that that the log4j.jar file is in the WAR file as @jowierun told you to?
Stephen C
@Stephen C - Yes, log4j-1.2.16.jar is in the WAR WEB-INF/lib directory, as well as: slf4j-api-1.5.8, slf4j-log4j12-1.5.6 and log4j.properties is in WEB-INF/classes
kgrad
@jowierun - no errors in the startup. I printed the classpath and it is exactly as shown within the war, both slf4j and log4j jars are present, still ignoring my properties file and using glassfish's jul logging instance to print to log.
kgrad
If it makes a difference, when I start glassfish it exports logging.properties to domain1/config.
kgrad
+3  A: 

Update: I tried to reproduce the issue. I created a simple Wicket project (same version as you):

mvn archetype:create \
-DarchetypeGroupId=org.apache.wicket \
-DarchetypeArtifactId=wicket-archetype-quickstart \
-DarchetypeVersion=1.4.9 \
-DgroupId=com.mycompany \
-DartifactId=my-wicketapp 

Which has a simple log4j.properties logging to the standard output.

log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n

log4j.rootLogger=INFO,Stdout

log4j.logger.org.apache.wicket=INFO
log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO
log4j.logger.org.apache.wicket.version=INFO
log4j.logger.org.apache.wicket.RequestCycle=INFO

Then:

  • I added all your dependencies (or modified the versions of existing one to match yours)
    • I just did some cleanup e.g. in the Hibernate dependencies, you don't need to declare them all, leverage the transitive dependencies mechanism
  • I added relevant repositories and pluginRepositories
  • I added glassfish's javax.servlet dependency to make the build pass
  • I added the embedded-glassfish plugin to test the whole thing
  • I made a few other unrelated changes
    • I changed the compiler settings to 1.6
    • I declared slf4j-api in the dependencyManagement element to control nicely the version in transitive dependencies.

The full pom.xml looks like this (so anybody can reproduce):

<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"&gt;
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>my-wicketapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <!-- TODO project name  -->
  <name>quickstart</name>
  <description/>
  <!--
        TODO <organization> <name>company name</name> <url>company url</url>
        </organization>
    -->
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt&lt;/url&gt;
      <distribution>repo</distribution>
    </license>
  </licenses>
  <repositories>
    <!-- For Hibernate Artifacts -->
    <repository>
      <id>repository.jboss.org-public</id>
      <name>JBoss repository</name>
      <url>https://repository.jboss.org/nexus/content/groups/public&lt;/url&gt;
    </repository>
    <!-- repository for Java EE 6 Binaries -->
    <repository>
      <id>java.net2</id>
      <name>Repository hosting the jee6 artifacts</name>
      <url>http://download.java.net/maven/2&lt;/url&gt;
    </repository>
  </repositories>
  <pluginRepositories>
    <!-- GlassFish repository for the embedded-glassfish plugin -->
    <pluginRepository>
      <id>glassfish</id>
      <name>GlassFish Maven 2 Repository</name>
      <url>http://download.java.net/maven/glassfish&lt;/url&gt;
    </pluginRepository>
  </pluginRepositories>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.5.5-Final</version>
    </dependency>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>r05</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.servlet</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>bean-validator</artifactId>
      <version>3.0-JBoss-4.0.0.Beta3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
    <!--  WICKET DEPENDENCIES -->
    <dependency>
      <groupId>org.apache.wicket</groupId>
      <artifactId>wicket</artifactId>
      <version>${wicket.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.wicket</groupId>
      <artifactId>wicket-auth-roles</artifactId>
      <version>${wicket.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jboss.weld</groupId>
      <artifactId>weld-wicket</artifactId>
      <version>1.0.1-Final</version>
    </dependency>
    <!--
            OPTIONAL <dependency> <groupId>org.apache.wicket</groupId>
            <artifactId>wicket-extensions</artifactId>
            <version>${wicket.version}</version> </dependency>
        -->
    <!-- LOGGING DEPENDENCIES - LOG4J -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
    </dependency>
    <!--  JUNIT DEPENDENCY FOR TESTING -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
    <!-- GLASSFISH EMBEDDED FOR TESTING -->
    <dependency>
      <groupId>org.glassfish.extras</groupId>
      <artifactId>glassfish-embedded-all</artifactId>
      <version>3.0.1</version>
      <scope>test</scope>
    </dependency>
    <!--  JETTY DEPENDENCIES FOR TESTING  -->
    <dependency>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>jetty</artifactId>
      <version>${jetty.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>jetty-util</artifactId>
      <version>${jetty.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>jetty-management</artifactId>
      <version>${jetty.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <filtering>false</filtering>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <filtering>false</filtering>
        <directory>src/main/java</directory>
        <includes>
          <include>**</include>
        </includes>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <filtering>false</filtering>
        <directory>src/test/java</directory>
        <includes>
          <include>**</include>
        </includes>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </testResource>
    </testResources>
    <plugins>
      <plugin>
        <inherited>true</inherited>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <optimize>true</optimize>
          <debug>true</debug>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>
          <downloadSources>true</downloadSources>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.glassfish</groupId>
        <artifactId>maven-embedded-glassfish-plugin</artifactId>
        <version>3.0.1</version>
        <configuration>
          <serverID>server</serverID>
          <name>server</name>
          <app>${project.build.directory}/${project.build.finalName}.war</app>
          <port>8080</port>
          <instanceRoot>${project.build.directory}/gfe-${maven.build.timestamp}</instanceRoot>
          <!--contextRoot>${build.finalName}</contextRoot-->
          <autoDelete>true</autoDelete>
          <!--configFile>${basedir}/domain.xml</configFile-->
        </configuration>
      </plugin>
    </plugins>
  </build>
  <properties>
    <wicket.version>1.4.9</wicket.version>
    <jetty.version>6.1.4</jetty.version>
    <slf4j.version>1.5.6</slf4j.version>
  </properties>
</project>

And when I run the project with the embedded-glassfish plugin:

$ mvn package
...
$ mvn embedded-glassfish:run
...

and access http://localhost:8080/server in a browser, I get my logs in the standard output as expected:

...
INFO: [WicketApplication] Started Wicket version 1.4.9 in development mode
********************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode.              ***
***                               ^^^^^^^^^^^                    ***
*** Do NOT deploy to your live server(s) without changing this.  ***
*** See Application#getConfigurationType() for more information. ***
********************************************************************

I wonder if this is representative or not.


I have checked the war, log4j.properties is indeed in WEB-INF/classes. I don't have a log4j.jar, i have slf4j-log4j12.jar.

slf4j-log4j12.jar is not a replacement for log4j.jar, slf4j-log4j12.jar is a binding for log4J version 1.2, you still need log4j.jar. From the SLF4J documentation:

Binding with a logging framework at deployment time

As mentioned previously, SLF4J supports various logging frameworks. The SLF4J distribution ships with several jar files referred to as "SLF4J bindings", with each binding corresponding to a supported framework.

slf4j-log4j12-1.6.1.jar: Binding for log4j version 1.2, a widely used logging framework. You also need to place log4j.jar on your class path.

I wonder how you got this working under NetBeans and Eclipse.

Pascal Thivent
I added log4j-1.2.14 to my maven dependencies, no luck, I verified that slf4j and log4j jars were indeed in my lib and log4j.properties is in WEB-INF/classes in my exploded war.
kgrad
@Pascal Thivent - Just to be completely sure I ran it again under netbeans and it is no longer logging properly there, which makes sense, I have no idea why it suddenly stopped using my log4j configuration... Perhaps I added a dependency that conflicts? Would pasting my pom help at all?
kgrad
@kgrad: Posting your pom would at least help to check the dependencies.
Pascal Thivent
@Pascal Thivent: posted.
kgrad
@Pascal Thivent: I changed my logger code to include org.apache.log4j.Logger and use Logger.getLogger() to test what was happening. Now my file appender creates a file, however the file is empty and the server log is still using glassfish's logger. Glassfish seems to be hijacking my logger instance and using its own somehow. I know that it atleast reads my config as the file is now being created, although empty...
kgrad
@kgrad: I'll run a simple test tonight (but I can already tell you that I'm using GlassFish 3 with SFL4F in my app without any problems).
Pascal Thivent
@Pascal Thivent - Any luck reproducing the issue? I don't think I'm doing anything non-standard, from everything I have read, it should just work if I have the proper jars on the classpath... It was working!
kgrad
@Pascal Thivent - I had a problem with glassfish which prompted me to reinstall, now I am getting this error in the log with log4j-1.2.16: log4j:ERROR log4j called after unloading, see http://logging.apache.org/log4j/1.2/faq.html#unload. java.lang.IllegalStateException: Class invariant violation... coming from GetLogger
kgrad
I had a bunch of repositories listed that I did not need, codehaus, ibiblio and an old jboss one, when I removed those but kept everything else the same it started working. I can only guess that one of those repositories had an old version of a library or was exporting something bad. Anyway marking your answer as accepted, thanks!
kgrad
@kgrad: Glad it's solved (even if I don't really understand how). And you're welcome.
Pascal Thivent
@kgrad: By the way, no bounty? :)
Pascal Thivent
@Pascal Thivent - That makes 2 of us (not understanding) I'm just happy it works and I'm not touching it anymore. The bounty expired yesterday! If you had only edited your stuff earlier! :(
kgrad
@kgrad: I did (before expiration) but I wasn't aware a bounty can just vanish. Was just curious.
Pascal Thivent
@Pascal Thivent - ah, didn't see it till this morning, feel kinda bad now, it's kinda silly that it disappears, my rep is gone into nothingness (you don't get it back), but bounties only last a week apparently.
kgrad
@kgrad: Oh, don't feel bad, and don't worry, I was really just asking to satisfy my curiosity.
Pascal Thivent
+1  A: 

Have a look at the log4j manual. The section "Default Initialization Procedure" describes how log4j will try to find the initialization file. Maybe you can try some of this options to get things work.

K. Claszen
+1  A: 

I suggest removing all the slf4j dependencies and change your logging code to use the Log4j API directly (if this is not too much work, don't know the size of your project). Once this works, consider if you really need the flexibility offered by slf4j. If you do, pick up the correct version of slf4j (slf4j-log4j12 might not be the correct one to use for log4j 1.2.16) and integrate it back in.

I encountered slf4j recently, and in the end removed it altogether because I ran into similar configuration problems.

Adriaan Koster
A: 

I have the following logging dependencies :

<dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>0.9.17</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.8</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.5.8</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
        <scope>runtime</scope>
    </dependency>

under /src/main/resources/ i have a logback.xml defining the various aspects (appenders,..). This gets picked up by maven and copied to WEB-INF/classes

hope that helped

bert
A: 

I would support Adriaan Koster's answer. If your pure log4j doesn't work however, try the following. Create simple class like this

import org.apache.log4j.Logger;
public class LogTest {
    private static Logger log;

    public static void main(String[] args) {
        log = Logger.getLogger(LogTest.class);
    }
}

...and put breakpoint in org.apache.log4j.helpers.Loader#getResource method. It tries to pull log4j.xml from classloader:

url = classLoader.getResource(resource);      

So you can easily look inside the classloader and see what paths it uses (and why it can't find your log4j.xml).

denis_k