Cannot subclass final class

1,700 views
Skip to first unread message

Raphael Bossek

unread,
Dec 8, 2010, 6:16:18 AM12/8/10
to PowerMock
Hi, you can find my simple project as ZIP and Maven3 project at the
following zip download url: http://bit.ly/hpVtYc
The mvn.log and org.raboss.javaexercise.ClassDefinitionTest.txt files
(part of the zip archive) document the problem.
To reproduce start "mvn test"

Using PowerMock 1.4.6 and maven-surefire-plugin 2.5

-------------------------------------------------------------------------------
Test set: org.raboss.javaexercise.ClassDefinitionTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.149
sec <<< FAILURE!
org.raboss.javaexercise.ClassDefinitionTest.testStaticMainMethods()
Time elapsed: 0.07 sec <<< FAILURE!
java.lang.IllegalArgumentException: Cannot subclass final class class
org.slf4j.LoggerFactory
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at
net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:
25)
at
net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:
216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at
org.easymock.internal.ClassProxyFactory.createProxy(ClassProxyFactory.java:
181)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:
60)
at org.powermock.api.easymock.PowerMock.doCreateMock(PowerMock.java:
2211)
at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2162)
at org.powermock.api.easymock.PowerMock.mockStatic(PowerMock.java:
296)
at
org.raboss.javaexercise.ClassDefinitionTest.testStaticMainMethods(ClassDefinitionTest.java:
45)

Here the test class src/test/java/org/raboss/javaexercise/
ClassDefinitionTest.java (from this zip archive):

package org.raboss.javaexercise;

import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.replayAll;
import static org.powermock.api.easymock.PowerMock.verifyAll;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.easymock.EasyMock.expect;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.*;
import org.powermock.modules.junit4.PowerMockRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Logger.class, LoggerFactory.class,
ClassDefinition.class})
@SuppressStaticInitializationFor({"org.slf4j.LoggerFactory"})
public class ClassDefinitionTest {
@Test public void testNonDefaultConstructur() {
final String msg = "testNonDefaultConstructur";
Logger mock = createMock(Logger.class);
mock.info(msg);
replayAll();
ClassDefinition probe = new ClassDefinition(mock);
probe.process(msg);
verifyAll();
}

@Test public void testStaticMainMethods() {
final String[] msg = new String[] {"testStaticMainMethod"};
Logger mockLogger = createMock(Logger.class);
// Mock all static methods.
mockStatic(LoggerFactory.class);

expect(LoggerFactory.getLogger(ClassDefinition.class)).andReturn(mockLogger);
mockLogger.info(msg[0]);
replayAll();
ClassDefinition.main(msg);
verifyAll();
}
}

The class under test (src/main/java/org/raboss/javaexercise/
ClassDefinition.java) looks like:

package org.raboss.javaexercise;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ClassDefinition {
private Logger logger;
ClassDefinition(Logger logger) {
this.logger = logger;
}
ClassDefinition() {
this(LoggerFactory.getLogger(ClassDefinition.class));
}
public static void main(final String[] args) {
ClassDefinition cd = new ClassDefinition();
if(0 == args.length) {
args[0] = "main";
}
cd.process(args[0]);
}
public final void setLogger(Logger logger) {
this.logger = logger;
}
public final void process(String msg) {
logger.info(msg);
}
}

In reference to http://www.slf4j.org/apidocs/org/slf4j/LoggerFactory.html
you can see that LoggerFactory is a final class.

Any help with this issue would be appreciated.
Greetings,
Raphael

Johan Haleby

unread,
Dec 8, 2010, 7:18:33 AM12/8/10
to powe...@googlegroups.com
Hmm strange. It works for me from Intellij but not from Maven. Wonder if it's a classpath issue.. 

/Johan


--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To post to this group, send email to powe...@googlegroups.com.
To unsubscribe from this group, send email to powermock+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/powermock?hl=en.


Raphael Bossek

unread,
Dec 8, 2010, 7:28:20 AM12/8/10
to powe...@googlegroups.com
Hi Johan,

it's working from Eclipse 3.6 too. I'm a little bit confused about the
output of "mvn -X test" and the maven-surefire-plugin's
junit:junit:3.8 reporting. I hope that junit 4.8.2 is used :

---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---
[DEBUG] Configuring mojo
org.apache.maven.plugins:maven-surefire-plugin:2.5:test from plugin
realm ClassRealm[plugin>org.apache.maven.plugins:maven-surefire-plugin:2.5,
parent: sun.misc.Launcher$AppClassLoader@f4a24a]
[DEBUG] Configuring mojo
'org.apache.maven.plugins:maven-surefire-plugin:2.5:test' with basic
configurator -->
[DEBUG] (f) basedir = /home/bossekr/workspace/exercise-1-1
[DEBUG] (f) childDelegation = false
[DEBUG] (f) classesDirectory =
/home/bossekr/workspace/exercise-1-1/target/classes
[DEBUG] (f) classpathElements =
[/home/bossekr/workspace/exercise-1-1/target/test-classes,
/home/bossekr/workspace/exercise-1-1/target/classes,
/home/bossekr/.m2/repository/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar,
/home/bossekr/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar,
/home/bossekr/.m2/repository/log4j/log4j/1.2.16/log4j-1.2.16.jar,
/home/bossekr/.m2/repository/org/easymock/easymock/3.0/easymock-3.0.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-module-junit4/1.4.6/powermock-module-junit4-1.4.6.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-module-junit4-common/1.4.6/powermock-module-junit4-common-1.4.6.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-api-easymock/1.4.6/powermock-api-easymock-1.4.6.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-api-support/1.4.6/powermock-api-support-1.4.6.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-core/1.4.6/powermock-core-1.4.6.jar,
/home/bossekr/.m2/repository/org/javassist/javassist/3.13.0-GA/javassist-3.13.0-GA.jar,
/home/bossekr/.m2/repository/org/powermock/powermock-reflect/1.4.6/powermock-reflect-1.4.6.jar,
/home/bossekr/.m2/repository/cglib/cglib-nodep/2.2/cglib-nodep-2.2.jar,
/home/bossekr/.m2/repository/org/objenesis/objenesis/1.2/objenesis-1.2.jar,
/home/bossekr/.m2/repository/junit/junit/4.8.2/junit-4.8.2.jar]
[DEBUG] (f) disableXmlReport = false
[DEBUG] (f) enableAssertions = true
[DEBUG] (f) forkMode = once
[DEBUG] (f) junitArtifactName = org.powermock:powermock-module-junit4
[DEBUG] (f) localRepository = id: local
url: file:///home/bossekr/.m2/repository/
layout: none

[DEBUG] (f) pluginArtifactMap =
{org.apache.maven.plugins:maven-surefire-plugin=org.apache.maven.plugins:maven-surefire-plugin:maven-plugin:2.5:,
org.apache.maven.surefire:surefire-booter=org.apache.maven.surefire:surefire-booter:jar:2.5:compile,
org.apache.maven.surefire:surefire-api=org.apache.maven.surefire:surefire-api:jar:2.5:compile,
org.codehaus.plexus:plexus-utils=org.codehaus.plexus:plexus-utils:jar:1.5.9:compile,
junit:junit=junit:junit:jar:3.8.1:compile,
org.apache.maven.reporting:maven-reporting-api=org.apache.maven.reporting:maven-reporting-api:jar:2.0.9:compile,
org.apache.maven.doxia:doxia-sink-api=org.apache.maven.doxia:doxia-sink-api:jar:1.0-alpha-10:compile,
commons-cli:commons-cli=commons-cli:commons-cli:jar:1.0:compile,
org.codehaus.plexus:plexus-interactivity-api=org.codehaus.plexus:plexus-interactivity-api:jar:1.0-alpha-4:compile}
[DEBUG] (f) printSummary = true
[DEBUG] (f) project = MavenProject:
org.raboss.javaexercises:exercise-1-1:0.0.1-SNAPSHOT @
/home/bossekr/workspace/exercise-1-1/pom.xml
[DEBUG] (f) projectArtifactMap =
{org.slf4j:slf4j-api=org.slf4j:slf4j-api:jar:1.6.1:compile,
org.slf4j:slf4j-log4j12=org.slf4j:slf4j-log4j12:jar:1.6.1:compile,
log4j:log4j=log4j:log4j:jar:1.2.16:compile,
org.easymock:easymock=org.easymock:easymock:jar:3.0:test,
org.powermock:powermock-module-junit4=org.powermock:powermock-module-junit4:jar:1.4.6:test,
org.powermock:powermock-module-junit4-common=org.powermock:powermock-module-junit4-common:jar:1.4.6:test,
org.powermock:powermock-api-easymock=org.powermock:powermock-api-easymock:jar:1.4.6:test,
org.powermock:powermock-api-support=org.powermock:powermock-api-support:jar:1.4.6:test,
org.powermock:powermock-core=org.powermock:powermock-core:jar:1.4.6:test,
org.javassist:javassist=org.javassist:javassist:jar:3.13.0-GA:test,
org.powermock:powermock-reflect=org.powermock:powermock-reflect:jar:1.4.6:test,
cglib:cglib-nodep=cglib:cglib-nodep:jar:2.2:test,
org.objenesis:objenesis=org.objenesis:objenesis:jar:1.2:test,
junit:junit=junit:junit:jar:4.8.2:test}
[DEBUG] (f) redirectTestOutputToFile = false
[DEBUG] (f) remoteRepositories = [ id: central
url: http://repo1.maven.org/maven2
layout: default
snapshots: [enabled => false, update => daily]
releases: [enabled => true, update => never]
]
[DEBUG] (f) reportFormat = brief
[DEBUG] (f) reportsDirectory =
/home/bossekr/workspace/exercise-1-1/target/surefire-reports
[DEBUG] (f) session = org.apache.maven.execution.MavenSession@14b081b
[DEBUG] (f) testClassesDirectory =
/home/bossekr/workspace/exercise-1-1/target/test-classes
[DEBUG] (f) testNGArtifactName = org.testng:testng
[DEBUG] (f) testSourceDirectory =
/home/bossekr/workspace/exercise-1-1/src/test/java
[DEBUG] (f) trimStackTrace = true
[DEBUG] (f) useFile = true
[DEBUG] (f) useManifestOnlyJar = true
[DEBUG] (f) workingDirectory = /home/bossekr/workspace/exercise-1-1
[DEBUG] -- end configuration --
[DEBUG] dummy:dummy:jar:1.0 (selected for null)
[DEBUG] org.apache.maven.surefire:surefire-booter:jar:2.5:compile
(selected for compile)
[DEBUG] org.apache.maven.surefire:surefire-api:jar:2.5:compile
(selected for compile)
[DEBUG] Adding to surefire booter test classpath:
/home/bossekr/.m2/repository/org/apache/maven/surefire/surefire-booter/2.5/surefire-booter-2.5.jar
[DEBUG] Adding to surefire booter test classpath:
/home/bossekr/.m2/repository/org/apache/maven/surefire/surefire-api/2.5/surefire-api-2.5.jar
[DEBUG] dummy:dummy:jar:1.0 (selected for null)
[DEBUG] org.apache.maven.surefire:surefire-junit:jar:2.5:test
(selected for test)
[DEBUG] junit:junit:jar:3.8.1:test (selected for test)
[DEBUG] org.apache.maven.surefire:surefire-api:jar:2.5:test
(selected for test)
[DEBUG] Adding to surefire test classpath:
/home/bossekr/.m2/repository/org/apache/maven/surefire/surefire-junit/2.5/surefire-junit-2.5.jar
[DEBUG] Adding to surefire test classpath:
/home/bossekr/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
[DEBUG] Adding to surefire test classpath:
/home/bossekr/.m2/repository/org/apache/maven/surefire/surefire-api/2.5/surefire-api-2.5.jar
[DEBUG] Test Classpath :
[DEBUG] /home/bossekr/workspace/exercise-1-1/target/test-classes
[DEBUG] /home/bossekr/workspace/exercise-1-1/target/classes
[DEBUG] /home/bossekr/.m2/repository/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar
[DEBUG] /home/bossekr/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar
[DEBUG] /home/bossekr/.m2/repository/log4j/log4j/1.2.16/log4j-1.2.16.jar
[DEBUG] /home/bossekr/.m2/repository/org/easymock/easymock/3.0/easymock-3.0.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-module-junit4/1.4.6/powermock-module-junit4-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-module-junit4-common/1.4.6/powermock-module-junit4-common-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-api-easymock/1.4.6/powermock-api-easymock-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-api-support/1.4.6/powermock-api-support-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-core/1.4.6/powermock-core-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/org/javassist/javassist/3.13.0-GA/javassist-3.13.0-GA.jar
[DEBUG] /home/bossekr/.m2/repository/org/powermock/powermock-reflect/1.4.6/powermock-reflect-1.4.6.jar
[DEBUG] /home/bossekr/.m2/repository/cglib/cglib-nodep/2.2/cglib-nodep-2.2.jar
[DEBUG] /home/bossekr/.m2/repository/org/objenesis/objenesis/1.2/objenesis-1.2.jar
[DEBUG] /home/bossekr/.m2/repository/junit/junit/4.8.2/junit-4.8.2.jar
[DEBUG] Setting system property
[user.dir]=[/home/bossekr/workspace/exercise-1-1]
[DEBUG] Setting system property [localRepository]=[/home/bossekr/.m2/repository]
[DEBUG] Setting system property [basedir]=[/home/bossekr/workspace/exercise-1-1]
[DEBUG] Using JVM: /usr/lib/jvm/java-6-sun-1.6.0.22/jre/bin/java
[INFO] Surefire report directory:
/home/bossekr/workspace/exercise-1-1/target/surefire-reports
Forking command line: /bin/sh -c cd
/home/bossekr/workspace/exercise-1-1 &&
/usr/lib/jvm/java-6-sun-1.6.0.22/jre/bin/java -jar
/tmp/surefirebooter1922467988786498550.jar
/tmp/surefire4338078243845467245tmp
/tmp/surefire6033892985670471542tmp

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.raboss.javaexercise.ClassDefinitionTest
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.13
sec <<< FAILURE!

Results :

Failed tests:
org.raboss.javaexercise.ClassDefinitionTest.testStaticMainMethods()

Tests run: 2, Failures: 1, Errors: 0, Skipped: 0

--->8--->8--->8--->8--->8--->8--->8--->8--->8--->8--->8--->8--->8--->8---

The related pom.xml content is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<junitArtifactName>org.powermock:powermock-module-junit4</junitArtifactName>
</configuration>
</plugin>

Interesting issue discussed about surefire and default junit can be fauld here:
http://stackoverflow.com/questions/2182376/surefire-is-not-picking-up-junit-4-tests

Greetings,
Raphael

2010/12/8 Johan Haleby <johan....@gmail.com>:

Johan Haleby

unread,
Dec 8, 2010, 8:22:11 AM12/8/10
to powe...@googlegroups.com
Yeah this is probably not a PowerMock issue. If you remove the surefire declaration from the pom it works (at least in maven 2), i.e. remove:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<junitArtifactName>org.powermock:powermock-module-junit4</junitArtifactName>
</configuration>
</plugin>

/Johan

Raphael Bossek

unread,
Dec 8, 2010, 9:52:31 AM12/8/10
to powe...@googlegroups.com
Hi Johan,

yes it's one step forward.
To get my pom.xml working with sonar-maven3-plugin:2.4.1 the
*maven-shade-plugin:1.4* plugin have to be removed/disabled.
Scenario: If maven-shade-plugin:1.4 is enabled the
maven-surefire-plugin:2.5 does not work if called by
sonar-maven3-plugin:2.4.1 in maven 3.0.1 (r1038046; 2010-11-23
11:58:32+0100).

Johan Haleby

unread,
Dec 8, 2010, 10:07:29 AM12/8/10
to powe...@googlegroups.com
Ok :/ Unfortunately I'm not sure if I can help you anymore. It seems to me that it's a problem with one of the maven plugins you're using. Correct me if I'm wrong.. Perhaps you should bring it up on the surefire, sonar or shade plugin mailing list as well?

/Johan

Raphael Bossek

unread,
Dec 8, 2010, 10:14:49 AM12/8/10
to powe...@googlegroups.com
Hi Johan,

thank you for you quick respond and support. The issue is solved for
so far. I'm writing already a not to the sonar mailing-list.

Johan Haleby

unread,
Dec 8, 2010, 10:23:24 AM12/8/10
to powe...@googlegroups.com
Ok good luck. Tell us if you find a work-around of some sort.

/Johan
Reply all
Reply to author
Forward
0 new messages