Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

ウェブアプリケーションサーバでよくあるクラスローダのトラブル


J2EE Advent Calendar25nobuokaJava Persistence API (JPA) 

developerWorksJ2EEOSGiJ2EE


class JavaJVMJRECLASSPATH1

EARWAR*1使WAREARskinny WAREAR


 @ developerWorks

WebSphere Application Server 8.0


2

1JARclass

a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html

2GitHub


使

JVM使GC

NAKAMURA MinoruJava  (Class Unloading)



warear使


Java pass
    @Test
    public void parentFirstHasNoMultiSingletonProblem() throws Exception {
        Object singletonInParent = findSingletonInstanceFrom(firstClassLoader);
        Object singletonInChild = findSingletonInstanceFrom(childOfFirstClassLoader);
        assertThat(singletonInChild, is(sameInstance(singletonInParent)));

        Object singletonInAnotherChild = findSingletonInstanceFrom(anotherChildOfFirstClassLoader);
        assertThat(singletonInAnotherChild, is(sameInstance(singletonInParent)));
        assertThat(singletonInAnotherChild, is(sameInstance(singletonInChild)));
    }




使

Oracle JREIBM JRE



JRElib/ext



2


developerWorks使staticJVM11


使




2
    @Test
    public void parentLastMayHaveMultiSingletonProblem() throws Exception {
        Object singletonInParent = findSingletonInstanceFrom(secondClassLoader);
        Object singletonInChild = findSingletonInstanceFrom(childOfSecondClassLoader);
        assertThat(singletonInChild, is(not(sameInstance(singletonInParent))));

        Object singletonInAnotherChild = findSingletonInstanceFrom(anotherChildOfSecondClassLoader);
        assertThat(singletonInAnotherChild, is(not(sameInstance(singletonInParent))));
        assertThat(singletonInAnotherChild, is(not(sameInstance(singletonInChild))));
    }

J2EE@Singleton


staticClass

singletonInstance
    @Test
    public void classLoaderShouldNotBeFinalizedIfSomeoneRefersIt() throws Exception {
        UnloadEventListener listener = new UnloadEventListener();
        Object singletonInstance = loadSingletonFromNewClassLoader(listener);
        assertThat(listener.unloaded, is(false));

        runFinalization(listener);
        assertThat("class loader should not be finalized, because we still use Singleton instance", listener.unloaded, is(false));
        System.out.printf("Singleton instance is %s%n", singletonInstance.getClass().getClassLoader()); // we should use singletonInstance like this, or optimization removes singletonInstance local variable
    }

Java

nekopJCLJakarta Commons LoggingJULjava.util.logging使


JVMJ2EEEJB


使GitHubJUnit使使


eller86/j2ee-class-loader-example


ObjectWeb ASM使

*1:アプリケーションサーバによっては設定で変更することも可能