diff --git a/demonstration/README.txt b/demonstration/README.txt
deleted file mode 100644
index 723bac6..0000000
--- a/demonstration/README.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2005 The Apache Software Foundation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-Contained are JCL Proof Of Concept Demonstrations
-
-The following jars must be added to this directory:
-
-Log4j.jar
-commons-logging.jar
-commons-logging-api.jar
-
-Create build directories by typing 'ant clean'
-Build by typing ant.
-
-Read the overview in the javadocs created under target/docs.
-
-When the time comes, run the demonstrations by typing 'ant run'
\ No newline at end of file
diff --git a/demonstration/build.xml b/demonstration/build.xml
deleted file mode 100644
index 891b994..0000000
--- a/demonstration/build.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-System.out.
- */
- public void runJCL() {
- try {
- SomeObject someObject = new SomeObject();
- System.out.println("--------------------");
- System.out.println("Logging to JCL:");
- someObject.logToJCL();
- System.out.println("JCL Logging OK");
- } catch (Throwable t) {
- System.out.println("JCL Logging FAILED: " + t.getClass());
- System.out.println(t.getMessage());
- System.out.println("");
- }
- }
-
- /**
- * Runs a test that logs to Log4J via static calls
- * and outputs the results to System.out.
- */
- public void runStatic() {
- try {
- SomeObject someObject = new SomeObject();
- System.out.println("--------------------");
- System.out.println("Logging to Static:");
- someObject.logToStaticLog4J();
- System.out.println("Static Logging: OK");
- } catch (Throwable t) {
- System.out.println("Static Logging FAILED: " + t.getClass());
- System.out.println(t.getMessage());
- System.out.println("");
- }
- }
-}
diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/SomeObject.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/SomeObject.java
deleted file mode 100644
index ca0ec93..0000000
--- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/SomeObject.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.logging.proofofconcept.caller;
-
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.logging.proofofconcept.staticlogger.StaticLog4JLogger;
-
-/**
- * This simulates some application or library code
- * that uses logging.
- * This separation allows tests to be run
- * where this class is defined by either the parent
- * or the child classloader.
- */
-public class SomeObject {
-
- /**
- * Logs a message to Jakarta Commons Logging.
- */
- public void logToJCL() {
- LogFactory.getLog("a log").info("A message");
- }
-
- /**
- * Logs a message to Log4j via a class
- * which makes a static call.
- */
- public void logToStaticLog4J() {
- StaticLog4JLogger.info("A message");
- }
-}
diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/package.html b/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/package.html
deleted file mode 100644
index 54aa603..0000000
--- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/caller/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
Invokes logging -and takes the role of calling application code in these demonstrations. -This separation allows a greater variety of defining classloaders for -the calling application code to be simulated. -
- - diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstClassLoader.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstClassLoader.java deleted file mode 100644 index 2c32552..0000000 --- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstClassLoader.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.logging.proofofconcept.runner; - -import java.net.URL; -import java.net.URLClassLoader; - -/** - * (Rather slack) implementation of a child first classloader. - * Should be fit for the purpose intended (which is demonstration) - * but a more complete and robust implementation should be - * preferred for more general purposes. - */ -public class ChildFirstClassLoader extends URLClassLoader { - - public ChildFirstClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - } - - protected synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException { - - // very basic implementation - Class result = findLoadedClass(name); - if (result == null) { - try { - result = findClass(name); - if (resolve) { - resolveClass(result); - } - } catch (ClassNotFoundException e) { - result = super.loadClass(name, resolve); - } - } - - return result; - } - -} diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstRunner.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstRunner.java deleted file mode 100644 index d69ab9d..0000000 --- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ChildFirstRunner.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.logging.proofofconcept.runner; - -import java.net.MalformedURLException; - - -/** - * Runs child first demonstrations. - * @see #main(String[]) - */ -public class ChildFirstRunner extends ClassLoaderRunner { - - - public ChildFirstRunner() throws MalformedURLException { - } - - - public void testCase17() { - int parentUrls = JCL_JAR + STATIC_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("17", parentUrls, childUrls, false, true); - } - - public void testCase18() { - int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("18", parentUrls, childUrls, false, true); - } - - public void testCase19() { - int parentUrls = JCL_JAR + STATIC_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("19", parentUrls, childUrls, true, true); - } - - public void testCase20() { - int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("20", parentUrls, childUrls, true, true); - } - - public void testCase21() { - int parentUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("21", parentUrls, childUrls, false, true); - } - - public void testCase22() { - int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("22", parentUrls, childUrls, false, true); - } - - public void testCase23() { - int parentUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("23", parentUrls, childUrls, true, true); - } - - public void testCase24() { - int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("24", parentUrls, childUrls, true, true); - } - - - public void testCase25() { - int parentUrls = API_JAR + STATIC_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("25", parentUrls, childUrls, false, true); - } - - public void testCase26() { - int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("26", parentUrls, childUrls, false, true); - } - - public void testCase27() { - int parentUrls = API_JAR + STATIC_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("27", parentUrls, childUrls, true, true); - } - - public void testCase28() { - int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("28", parentUrls, childUrls, true, true); - } - - public void testCase29() { - int parentUrls = API_JAR + STATIC_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("29", parentUrls, childUrls, false, true); - } - - public void testCase30() { - int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("30", parentUrls, childUrls, false, true); - } - - public void testCase31() { - int parentUrls = API_JAR + STATIC_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - run("31", parentUrls, childUrls, true, true); - } - - public void testCase32() { - int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR; - int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR; - run("32", parentUrls, childUrls, true, true); - } - - /** - * Runs all child first cases. - * @param args - */ - public static void main(String[] args) - { - ChildFirstRunner runner; - try { - runner = new ChildFirstRunner(); - System.out.println(""); - System.out.println(""); - System.out.println("Running Child First Cases..."); - System.out.println(""); - System.out.println(""); - runner.testCase17(); - runner.testCase18(); - runner.testCase19(); - runner.testCase20(); - runner.testCase21(); - runner.testCase22(); - runner.testCase23(); - runner.testCase24(); - runner.testCase25(); - runner.testCase26(); - runner.testCase27(); - runner.testCase28(); - runner.testCase29(); - runner.testCase30(); - runner.testCase31(); - runner.testCase32(); - } catch (MalformedURLException e) { - System.out.println("Cannot find required jars"); - e.printStackTrace(); - } - - } -} diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ClassLoaderRunner.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ClassLoaderRunner.java deleted file mode 100644 index a486e39..0000000 --- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ClassLoaderRunner.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.logging.proofofconcept.runner; - -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; - - -/** - * Runs demonstrations with complex classloader hierarchies - * and outputs formatted descriptions of the tests run. - */ -public class ClassLoaderRunner { - - private static final Class[] EMPTY_CLASSES = {}; - private static final Object[] EMPTY_OBJECTS = {}; - private static final URL[] EMPTY_URLS = {}; - - public static final int LOG4J_JAR = 1 << 0; - public static final int STATIC_JAR = 1 << 1; - public static final int JCL_JAR = 1 << 2; - public static final int CALLER_JAR = 1 << 3; - public static final int API_JAR = 1 << 4; - - private final URL log4jUrl; - private final URL staticUrl; - private final URL jclUrl; - private final URL callerUrl; - private final URL apiUrl; - - /** - * Loads URLs. - * @throws MalformedURLException when any of these URLs cannot - * be resolved - */ - public ClassLoaderRunner() throws MalformedURLException { - log4jUrl = new URL("file:log4j.jar"); - staticUrl = new URL("file:static.jar"); - jclUrl = new URL("file:commons-logging.jar"); - callerUrl = new URL("file:caller.jar"); - apiUrl = new URL("file:commons-logging-api.jar"); - } - - /** - * Runs a demonstration. - * @param caseName human name for test (used for output) - * @param parentJars bitwise code for jars to be definable - * by the parent classloader - * @param childJars bitwise code for jars to be definable - * by the child classloader - * @param setContextClassloader true if the context classloader - * should be set to the child classloader, - * false preserves the default - * @param childFirst true if the child classloader - * should delegate only if it cannot define a class, - * false otherwise - */ - public void run(String caseName, int parentJars, int childJars, - boolean setContextClassloader, boolean childFirst) { - - System.out.println(""); - System.out.println("*****************************"); - System.out.println(""); - System.out.println("Running case " + caseName + "..."); - System.out.println(""); - URL[] parentUrls = urlsForJars(parentJars, "Parent Classloader: "); - URL[] childUrls = urlsForJars(childJars, "Child Classloader: "); - System.out.println("Child context classloader: " + setContextClassloader); - System.out.println("Child first: " + childFirst); - System.out.println(""); - run("org.apache.commons.logging.proofofconcept.caller.JCLDemonstrator", - parentUrls, childUrls, setContextClassloader, childFirst); - System.out.println("*****************************"); - } - - /** - * Converts a bitwise jar code into an array of URLs - * containing approapriate URLs. - * @param jars bitwise jar code - * @param humanLoaderName human name for classloader - * @returnURL array, not null possibly empty
- */
- private URL[] urlsForJars(int jars, String humanLoaderName) {
- List urls = new ArrayList();;
- if ((LOG4J_JAR & jars) > 0) {
- urls.add(log4jUrl);
- }
- if ((STATIC_JAR & jars) > 0) {
- urls.add(staticUrl);
- }
- if ((JCL_JAR & jars) > 0) {
- urls.add(jclUrl);
- }
- if ((API_JAR & jars) > 0) {
- urls.add(apiUrl);
- }
- if ((CALLER_JAR & jars) > 0) {
- urls.add(callerUrl);
- }
- System.out.println(humanLoaderName + " " + urls);
- URL[] results = (URL[]) urls.toArray(EMPTY_URLS);
- return results;
- }
-
- /**
- * Runs a demonstration.
- * @param testName the human name for this test
- * @param parentClassloaderUrls the URL's which should
- * be definable by the parent classloader, not null
- * @param childClassloaderUrls the URL's which should
- * be definable by the child classloader, not null
- * @param setContextClassloader true if the context
- * classloader should be set to the child classloader,
- * false if the default context classloader should
- * be maintained
- * @param childFirst true if the child classloader
- * should delegate only when it cannot define the class,
- * false otherwise
- */
- public void run (String testName,
- URL[] parentClassloaderUrls,
- URL[] childClassloaderUrls,
- boolean setContextClassloader,
- boolean childFirst) {
-
- URLClassLoader parent = new URLClassLoader(parentClassloaderUrls);
- URLClassLoader child = null;
- if (childFirst) {
- child = new ChildFirstClassLoader(childClassloaderUrls, parent);
- } else {
- child = new URLClassLoader(childClassloaderUrls, parent);
- }
-
- if (setContextClassloader) {
- Thread.currentThread().setContextClassLoader(child);
- } else {
- ClassLoader system = ClassLoader.getSystemClassLoader();
- Thread.currentThread().setContextClassLoader(system);
- }
-
- logDefiningLoaders(child, parent);
-
- try {
-
- Class callerClass = child.loadClass(testName);
- Method runMethod = callerClass.getDeclaredMethod("run", EMPTY_CLASSES);
- Object caller = callerClass.newInstance();
- runMethod.invoke(caller, EMPTY_OBJECTS);
-
- } catch (Exception e) {
- System.out.println("Cannot execute test: " + e.getMessage());
- e.printStackTrace();
- }
-
- }
-
- /**
- * Logs the classloaders which define important classes
- * @param child child ClassLoader, not null
- * @param parent parent ClassLoader, not null
- */
- private void logDefiningLoaders(ClassLoader child, ClassLoader parent)
- {
- System.out.println("");
- logDefiningLoaders(child, parent, "org.apache.commons.logging.LogFactory", "JCL ");
- logDefiningLoaders(child, parent, "org.apache.log4j.Logger", "Log4j ");
- logDefiningLoaders(child, parent, "org.apache.commons.logging.proofofconcept.staticlogger.StaticLog4JLogger", "Static Logger");
- logDefiningLoaders(child, parent, "org.apache.commons.logging.proofofconcept.caller.SomeObject", "Caller ");
- System.out.println("");
- }
-
- /**
- * Logs the classloader which defines the class with the given name whose
- * loading is initiated by the child classloader.
- * @param child child ClassLoader, not null
- * @param parent parent ClassLoader, not null
- * @param className name of the class to be loaded
- * @param humanName the human name for the class
- */
- private void logDefiningLoaders(ClassLoader child, ClassLoader parent, String className, String humanName) {
- try {
- Class clazz = child.loadClass(className);
- ClassLoader definingLoader = clazz.getClassLoader();
- if (definingLoader == null)
- {
- System.out.println(humanName + " defined by SYSTEM class loader");
- }
- else if (definingLoader.equals(child))
- {
- System.out.println(humanName + " defined by CHILD class loader");
- }
- else if (definingLoader.equals(parent))
- {
- System.out.println(humanName + " defined by PARENT class loader");
- }
- else
- {
- System.out.println(humanName + " defined by OTHER class loader");
- }
- } catch (Exception e) {
- System.out.println(humanName + " NOT LOADABLE by application classloader");
- }
- }
-
-}
diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ParentFirstRunner.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ParentFirstRunner.java
deleted file mode 100644
index 5c102ae..0000000
--- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/ParentFirstRunner.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.logging.proofofconcept.runner;
-
-import java.net.MalformedURLException;
-
-
-/**
- * Runs parent first demonstrations.
- * @see #main(String[])
- */
-public class ParentFirstRunner extends ClassLoaderRunner {
-
-
- public ParentFirstRunner() throws MalformedURLException {
- }
-
- public void testCase1() {
- int parentUrls = JCL_JAR + STATIC_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("1", parentUrls, childUrls, false, false);
- }
-
- public void testCase2() {
- int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("2", parentUrls, childUrls, false, false);
- }
-
- public void testCase3() {
- int parentUrls = JCL_JAR + STATIC_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("3", parentUrls, childUrls, true, false);
- }
-
- public void testCase4() {
- int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("4", parentUrls, childUrls, true, false);
- }
-
- public void testCase5() {
- int parentUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("5", parentUrls, childUrls, false, false);
- }
-
- public void testCase6() {
- int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("6", parentUrls, childUrls, false, false);
- }
-
- public void testCase7() {
- int parentUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("7", parentUrls, childUrls, true, false);
- }
-
- public void testCase8() {
- int parentUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("8", parentUrls, childUrls, true, false);
- }
-
-
- public void testCase9() {
- int parentUrls = API_JAR + STATIC_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("9", parentUrls, childUrls, false, false);
- }
-
- public void testCase10() {
- int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("10", parentUrls, childUrls, false, false);
- }
-
- public void testCase11() {
- int parentUrls = API_JAR + STATIC_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("11", parentUrls, childUrls, true, false);
- }
-
- public void testCase12() {
- int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("12", parentUrls, childUrls, true, false);
- }
-
- public void testCase13() {
- int parentUrls = API_JAR + STATIC_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("13", parentUrls, childUrls, false, false);
- }
-
- public void testCase14() {
- int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("14", parentUrls, childUrls, false, false);
- }
-
- public void testCase15() {
- int parentUrls = API_JAR + STATIC_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- run("15", parentUrls, childUrls, true, false);
- }
-
- public void testCase16() {
- int parentUrls = API_JAR + STATIC_JAR + CALLER_JAR + LOG4J_JAR;
- int childUrls = JCL_JAR + STATIC_JAR + LOG4J_JAR;
- run("16", parentUrls, childUrls, true, false);
- }
-
- /**
- * Runs all parent first cases.
- * @param args
- */
- public static void main(String[] args)
- {
- ParentFirstRunner runner;
- try {
- runner = new ParentFirstRunner();
-
- System.out.println("");
- System.out.println("");
- System.out.println("Running Parent First Cases...");
- System.out.println("");
- System.out.println("");
- runner.testCase1();
- runner.testCase2();
- runner.testCase3();
- runner.testCase4();
- runner.testCase5();
- runner.testCase6();
- runner.testCase7();
- runner.testCase8();
- runner.testCase9();
- runner.testCase10();
- runner.testCase11();
- runner.testCase12();
- runner.testCase13();
- runner.testCase14();
- runner.testCase15();
- runner.testCase16();
- } catch (MalformedURLException e) {
- System.out.println("Cannot find required jars");
- e.printStackTrace();
- }
-
- }
-}
diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/package.html b/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/package.html
deleted file mode 100644
index 94723ea..0000000
--- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/runner/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-Runs the demonstrations.
--Also contained is utility code that efficiently sets up the -various classloader hierarchies. -
- diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/StaticLog4JLogger.java b/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/StaticLog4JLogger.java deleted file mode 100644 index 8d8b2e8..0000000 --- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/StaticLog4JLogger.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.logging.proofofconcept.staticlogger; - -import org.apache.log4j.Logger; - - - -/** - * This simulates a simple, static binding to Log4J. - */ -public class StaticLog4JLogger { - - public static void info(String message) { - // could have got the logger at the start - Logger.getLogger("Whatever").info(message); - } - -} diff --git a/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/package.html b/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/package.html deleted file mode 100644 index 8e081c8..0000000 --- a/demonstration/src/java/org/apache/commons/logging/proofofconcept/staticlogger/package.html +++ /dev/null @@ -1,25 +0,0 @@ - - -Calls Log4j. Uses a symbolic reference. -
--This allows practical demonstrations of the behaviour of code -that calls Log4J statically when placed in similar -classloader circumstances of JCL. -
- diff --git a/demonstration/src/java/overview.html b/demonstration/src/java/overview.html deleted file mode 100644 index 9ae10f0..0000000 --- a/demonstration/src/java/overview.html +++ /dev/null @@ -1,835 +0,0 @@ - - - - -This document contains analysis of various JCL use cases. It works -both as an educational document and as a specification (of sorts). -It's intended audience are (potential) JCL developers and (potential) -expert users. The code that accompanies -this document demonstrates the cases analysed in the text. -
-Familiarity with (advanced) class loading -concepts and terminology is assumed. Please digest the -JCL -Technology Guide before starting. -
-This approach was inspired by a -JCL critique -written by Ceki Gülcü. -
-These demonstrations focus on discovery in general and discovery -of Log4J in particular. Not only is Log4J the most important target -but these are some of the most difficult and contentious cases. -Lessons learnt from these cases should easily and safely extrapolate -to other cases. -
-It is important that this document is as accurate as possible both -in facts and analysis. Readers are encouraged to contribute -corrections and improvements. Please either: -
-The basic set up for these demonstrations is intentionally simple. -There are no tricks that might obscure a clear view of the concepts. -The source code used to run these demonstrations is simple and should -be easy to understand. -
-Each demonstration is initiated by a runner. The runner loads the -other code components into appropriate ClassLoaders and then calls the caller. -
-The caller is used to simulate a class that needs to log -something. It is isolated from the code that runs the demonstration -in order to allow a greater variety of ClassLoader situations to be simulated. -The calling code is split -into one class that presents the formatted results and another that -actually performs the calls. Calls are made to JCL and to a static -logger. -
-The static logger simply contains a call directly to Log4J. This -is useful for comparison. -
-Now would be a good idea to study the javadocs. -
-Results are printed (with a little formatting) to System.out. The -run target in the ant build scripts runs all cases. It may be -difficult to run these demonstrations from an IDE (a clean system -ClassLoader is required). -
-This analysis will start by making a division between conventional -context classloaders and unconventional ones. Conventionally, the -context classloader for a thread executing code in a particular class -should either be the classloader used to load the class, an ancestor -of that classloader or a descendent of it. The conventional context -classloader cases will focus on context classloaders which obey these -rules. -
-The aim of the set up will be isolate the essentials. Only three -classloaders will be considered: -
-This situation is commonly encountered in containers (where the -child classloader is the application classloader). In practical -situations, the hierarchy is likely to be contain more classloaders -but it should be possible either to extrapolate from these simple -cases or reduce the more complex ones to these. -
-The analysis will proceed by considering two cases separately: -
-In the parent first cases, when the child classloader initiates -loading, it starts by delegating to the parent classloader. Only if -this classloader does not define the class will the child classloader -attempt to define the class. In the child first cases, the child -classloader will begin by attempting to define the class itself. Only -when it cannot define a class will it delegate to it's parents. -Further discussion of each of these cases will be contained in the -appropriate section. -
-The other variable is the setting of the context classloader. In -these cases, it will be set to either the system classloader (the -default) or the child classloader (the application classloader). -Perhaps the cases for setting to the parent classloader -should be added (but this would be unusual: conventionally the context -classloader should be either unset or set to the application -classloader). Contributions of these extra cases would be welcomed. -
-The cases will be presented in a matrix. This contains details of -the classloader set ups including which -which classes are definable by which loaders and how the context -classloader is set. It also contains the results of analysis about -the way that both the static logging and JCL (ideally) should behave. -
-For example -
-| Context ClassLoader | -System | -
|---|---|
| Parent | -JCL+Static | -
| Child | -
- JCL+Static - Log4J - Caller - |
-
| Expected Result | -JCL->java.util - static FAIL - |
-
This describes a case where the context classloader is unset (and -so defaults to the system), the static.jar and commons-logging.jar -are definable by the parent classloader, the static.jar, -commons-logging.jar and log4j are definable by the child. The -caller.jar is also definable by the child classloader. The expected -result in this case is that JCL will discover java.util.logging and -that logging statically to Log4j will fail. -
-For purposes of reference, an indication is given in those cases -that correspond to examples used by Ceki in his critique. -
-Analytical notes explaining how these results were obtained are -included below each table. As the cases proceed, the notes will grow -more terse. -
-| Case | -1 | -2 | -3 | -4 | -
|---|---|---|---|---|
| Ceki Example | -- | -1 | -2A | -3 | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -JCL+Static | -JCL+Static Caller | -JCL+Static | -JCL+Static Caller | -
| Child | -
- JCL+Static - Log4J - Caller |
-
- JCL+Static - Log4J - |
-
- JCL+Static - Log4J - Caller - |
-
- JCL+Static - Log4J - |
-
| Expected Result | -
- JCL->java.util - static FAIL - |
-
- JCL->java.util - static FAIL - |
-
- JCL->java.util - static FAIL - |
-
- JCL->java.util - static FAIL - |
-
One important point to bear in mind when analysing parent-first -classloaders is that the presence or absence in the child classloader -of classes definable by the parent classloader produces no difference -in behaviour: the parent classloader will always load the class in -question. -
-In the cases above, Log4J is defined (only) by the child and all -JCL classes by the parent classloader. The symbolic references from -Log4JLogger to Log4J classes therefore cannot be resolved as Log4j is -not definable by the parent classloader. For the same reason, the -static call should also always fail. -
-The context classloader can be of no use (whether set or not) -since Log4JLogger will always be defined by the parent classloader -whether loading is initiated by the child or by the parent loader. -
-Therefore, in these cases, the appropriate behaviour is for JCL to -discover that java.util.logging is the only available logging system. -
-| Case | -5 | -6 | -7 | -8 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -Log4J - JCL+Static - | Log4J - JCL+Static - Caller - | Log4J - JCL+Static - |
- Log4J - JCL+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result - | -JCL->log4j - static OK - |
- JCL->log4j - static OK - |
-
- JCL->log4j - static OK - |
-
- JCL->log4j - static OK - |
-
This demonstrates the usual way to fix the problems encountered -when Log4J is not definable by the loader that defines JCL: just add -the Log4j.jar into the classloader that defines JCL. -
-This is a very simple set of cases with JCL and static being able -to resolve the appropriate symbolic references to Log4j directly. -Whether the context classloader is set or not in these cases should -make no difference. -
-| Case | -9 | -10 | -11 | -12 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -API+Static | -API+Static - Caller - |
- API+Static - | -API+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result | -JCL->java.util - static FAIL - |
- JCL->java.util - static FAIL - |
- JCL->log4j - static FAIL - |
- JCL->log4j - static FAIL - |
-
These demonstrate variations on the first series of cases where -Log4J is defined by the child. The placement of the static jar does -not vary (from the previous set) and again is expected to -consistently fail. -
-This time the API jar is placed in the parent classloader and the -full JCL jar in the child. This means that the symbolic reference -from the Log4JLogger class (contained in the full jar but not the -API) to Log4J classes can be resolved. -
-In these cases, whether JCL can succeed depends on the context -classloader. The delegation model employed by Java ClassLoaders -allows child classloaders to know about parents but not vice versa. -Therefore, the context classloader is the only means available to -attempt to load Log4JLogger. When the context classloader is set to -the child, this classloader defines Log4JLogger and Log4J. Therefore, -JCL should be able to discover Log4J (only) when the context -classloader is set to the child. -
-| Case | -13 | -14 | -15 | -16 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -Log4J - API+Static - |
- Log4J - API+Static - Caller - |
- Log4J - API+Static - |
- Log4J - API+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller |
- JCL+Static - Log4J |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J |
-
| Expected Result | -JCL->java.util - static OK |
- JCL->java.util - static OK - |
- JCL->log4j - static OK - |
- JCL->log4j - static OK - |
-
Trivial variations on the second series. Now API and JCL are -definable only by parent and child respectively (as in the last -series). When the context classloader is set to system, -Log4JLogger cannot be loaded and so java.util.logging is the only viable -logger. -
-The same classloader configuration can be repeated with (this -time) child-first classloading. -
-| Case | -17 | -18 | -19 | -20 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -5 | -6 | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -JCL+Static | -JCL+Static - Caller |
- JCL+Static | -JCL+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result | -JCL->Log4j - static OK - |
- JCL->java.util - static FAIL - |
- JCL->Log4j - static OK - |
- JCL->java.util - static FAIL - |
-
In child-first cases, the classloader which defines the caller -plays a more important role. When the caller is defined by the child -classloader, both static and JCL should succeed whether the context -classloader is set or not. -
-When the caller is defined by the parent classloader, this means -that the parent classloader will define the JCL and static classes -(rather than the child). Log4J is not defined by the parent loader -and so the static call must fail in both cases. -
-With a friendly context classloader, JCL can load an instance of -Log4JLogger whose symbolic references to Log4J can be resolved. -However, the child classloader which defines this class will resolve -the symbolic reference to Log to the class defined by the child -classloader rather than the Log class defined by the parent -classloader. They are not mutually accessible and so JCL must -discover java.util.logging. -
-| Case - | -21 | -22 | -23 | -24 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -Log4J - JCL+Static - |
- Log4J - JCL+Static - Caller - |
- Log4J - JCL+Static - |
- Log4J - JCL+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result | -JCL->log4j - static OK - |
- JCL->log4j - static OK - |
- JCL->log4j - static OK - |
- JCL->log4j - static OK - |
-
Trivial case where jar's are definable by both loaders. -
-| Case | -25 | -26 | -27 | -28 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -API+Static | -API+Static - Caller - |
- API+Static | -API+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result | -JCL->log4j - static OK - |
- JCL->java.util - static FAIL - |
- JCL->log4j - static OK - |
- JCL->java.util - static FAIL - |
-
(As above) to succeed, the static call requires that Log4J is -definable by the loader which defines the callers. JCL should -discover Log4J in the cases where the static call succeeds. -
-Even with a friendly context classloader, the Log class referenced -by the Log4JLogger defined by the child classloader will be -inaccessible to the caller (loader by the parent classloader). -
-| Case | -29 | -30 | -31 | -32 | -
|---|---|---|---|---|
| Ceki Example | -- | -- | -- | -- | -
| Context ClassLoader | -System | -System | -Child | -Child | -
| Parent | -Log4J - API+Static - |
- Log4J - API+Static - Caller - |
- Log4J - API+Static - |
- Log4J - API+Static - Caller - |
-
| Child | -JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
- JCL+Static - Log4J - Caller - |
- JCL+Static - Log4J - |
-
| Expected Result | -JCL->log4j - static OK - |
- JCL->java.util - static OK - |
- JCL->log4j - static OK - |
- JCL->java.util - static OK - |
-
These results at first glance may seem a little confusing. The -issue for JCL is that classes needed to log to Log4J are only -definable by the child classloader. -
-Even with a friendly context classloader, JCL runs into the same -difficulties with accessibility that -occurred above. -
- -