package myorg.mypackage.ex1;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class App {
private static Log log = LogFactory.getLog(App.class);
public int returnOne() {
//System.out.println( "Here's One!" );
log.debug( "Here's One!" );
return 1;
}
public static void main( String[] args ) {
//System.out.println( "Hello World!" );
log.info( "Hello World!" );
}
}package myorg.mypackage.ex1;
...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AppTest {
private static Log log = LogFactory.getLog(AppTest.class);
...
@Test
public void testApp() {
//System.out.println("testApp");
log.info("testApp");
App app = new App();
assertTrue("app didn't return 1", app.returnOne() == 1);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/>
</layout>
</appender>
<appender name="logfile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="target/log4j-out.txt"/>
<param name="Append" value="false"/>
<param name="MaxFileSize" value="100KB"/>
<param name="MaxBackupIndex" value="1"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-5p %d{dd-MM HH:mm:ss,SSS} [%c] (%F:%M:%L) -%m%n"/>
</layout>
</appender>
<logger name="myorg.mypackage">
<level value="debug"/>
<appender-ref ref="logfile"/>
</logger>
<root>
<priority value="info"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>> find . -type f ./src/main/java/myorg/mypackage/ex1/App.java ./src/test/java/myorg/mypackage/ex1/AppTest.java ./src/test/resources/log4j.xml ./build.properties ./build.xml
# ex1 build.properties
commons.logging.classpath=${M2_REPO}/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
log4j.classpath=${M2_REPO}/log4j/log4j/1.2.13/log4j-1.2.13.jar <target name="echo">
...
<echo>commons.logging.classpath=${commons.logging.classpath}</echo>
<echo>log4j.classpath=${log4j.classpath}</echo>
</target> <javac srcdir="${src.dir}/main/java"
destdir="${build.dir}/classes"
debug="true"
source="1.6"
target="1.6">
<classpath>
<pathelement path="${commons.logging.classpath}"/>
</classpath>
</javac> <javac srcdir="${src.dir}/test/java"
destdir="${build.dir}/test-classes"
debug="true"
source="1.6"
target="1.6">
<classpath>
<pathelement location="${build.dir}/${artifactId}.jar"/>
<pathelement path="${junit.classpath}"/>
<pathelement path="${commons.logging.classpath}"/>
</classpath>
</javac>
<copy todir="${build.dir}/test-classes">
<fileset dir="${src.dir}/test/resources"/>
</copy> <junit printsummary="true" showoutput="true" fork="true">
<classpath>
<pathelement path="${junit.classpath}"/>
<pathelement location="${build.dir}/${artifactId}.jar"/>
<pathelement location="${build.dir}/test-classes"/>
<pathelement path="${commons.logging.classpath}"/>
<pathelement path="${log4j.classpath}"/>
</classpath>
...$ ant clean test
Buildfile: build.xml
clean:
[delete] Deleting directory C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target
package:
[mkdir] Created dir: C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\classes
[javac] Compiling 1 source file to C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\classes
[jar] Building jar: C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\ex1.jar
test:
[mkdir] Created dir: C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\test-classes
[javac] Compiling 1 source file to C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\test-classes
[copy] Copying 1 file to C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\test-classes
[mkdir] Created dir: C:\cygwin\home\jcstaff\proj\784\exercises\ex1\target\test-reports
[junit] Running myorg.mypackage.ex1.AppTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.032 sec
BUILD SUCCESSFUL
Total time: 2 seconds$ more target/test-reports/TEST-myorg.mypackage.ex1.AppTest.txt Testsuite: myorg.mypackage.ex1.AppTest Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.032 sec ------------- Standard Output --------------- INFO 30-08 18:23:34,062 (AppTest.java:testApp:28) -testApp DEBUG 30-08 18:23:34,062 (App.java:returnOne:11) -Here's One! ------------- ---------------- --------------- Testcase: testApp took 0 sec
$ more target/log4j-out.txt INFO 30-08 18:23:34,062 [myorg.mypackage.ex1.AppTest] (AppTest.java:testApp:28) -testApp DEBUG 30-08 18:23:34,062 [myorg.mypackage.ex1.App] (App.java:returnOne:11) -Here's One!
> find . -type f ./src/main/java/myorg/mypackage/ex1/App.java ./src/test/java/myorg/mypackage/ex1/AppTest.java ./src/test/resources/log4j.xml ./build.properties ./build.xml ./target/classes/myorg/mypackage/ex1/App.class ./target/ex1.jar ./target/test-classes/myorg/mypackage/ex1/AppTest.class ./target/test-classes/log4j.xml ./target/test-reports/TEST-myorg.mypackage.ex1.AppTest.txt ./target/test-reports/TEST-myorg.mypackage.ex1.AppTest.xml ./target/log4j-out.txt
<logger name="myorg.mypackage.ex1.App">
<level value="debug"/>
<appender-ref ref="logfile"/>
</logger> [junit] Running myorg.mypackage.ex1.AppTest
[junit] INFO 01-09 13:13:19,343 (AppTest.java:testApp:26) -testApp
[junit] DEBUG 01-09 13:13:19,351 (App.java:returnOne:11) -Here's One!
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec
BUILD SUCCESSFUL
Total time: 2 seconds> more target/log4j-out.txt DEBUG 01-09 13:13:19,351 [myorg.mypackage.ex1.App] (App.java:returnOne:11) -Here's One!
In this part of the exercise, you were given a taste of how to get started adding the commons-logging framework to your components and deferring the implementation and configuration of the logger until runtime. This is a general topic that will come up in any Java development project, but is more critical when integrating independent components into a runtime environment.
The details of commons-logging and log4j are beyond the scope of what can be covered in an intro exercise. Read through some of the references and modify your implementation to test