You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:20:57 UTC
[sling-org-apache-sling-commons-compiler] 05/09: SLING-2447 :
ClassLoaderWriter should provide class loader for loading written
classes/resources
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.commons.compiler-2.0.4
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-compiler.git
commit 2e97b65052a61f938fe8e48ddea14cede3600a4e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Mar 23 14:53:38 2012 +0000
SLING-2447 : ClassLoaderWriter should provide class loader for loading written classes/resources
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/commons/compiler@1304391 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 2 +-
.../compiler/impl/CompilationResultImpl.java | 15 +-
.../commons/compiler/impl/EclipseJavaCompiler.java | 64 ++------
.../commons/compiler/impl/IsolatedClassLoader.java | 162 +++++++++++++++++++++
.../commons/compiler/impl/CompilerJava5Test.java | 7 +
5 files changed, 188 insertions(+), 62 deletions(-)
diff --git a/pom.xml b/pom.xml
index b5752ee..1d68d32 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.classloader</artifactId>
- <version>1.1.0</version>
+ <version>1.2.5-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java b/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java
index 83baef6..5d878b2 100644
--- a/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java
+++ b/src/main/java/org/apache/sling/commons/compiler/impl/CompilationResultImpl.java
@@ -19,6 +19,7 @@ package org.apache.sling.commons.compiler.impl;
import java.util.ArrayList;
import java.util.List;
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
import org.apache.sling.commons.compiler.CompilationResult;
import org.apache.sling.commons.compiler.CompilerMessage;
@@ -35,25 +36,25 @@ public class CompilationResultImpl implements CompilationResult {
private final boolean compilationRequired;
- private final ClassLoader classLoader;
+ private final ClassLoaderWriter classLoaderWriter;
public CompilationResultImpl(final String errorMessage) {
this.ignoreWarnings = true;
- this.classLoader = null;
+ this.classLoaderWriter = null;
this.compilationRequired = false;
this.onError(errorMessage, "<General>", 0, 0);
}
- public CompilationResultImpl(final ClassLoader classLoader) {
+ public CompilationResultImpl(final ClassLoaderWriter writer) {
this.ignoreWarnings = true;
- this.classLoader = classLoader;
+ this.classLoaderWriter = writer;
this.compilationRequired = false;
}
public CompilationResultImpl(final boolean ignoreWarnings,
- final ClassLoader classLoader) {
+ final ClassLoaderWriter writer) {
this.ignoreWarnings = ignoreWarnings;
- this.classLoader = classLoader;
+ this.classLoaderWriter = writer;
this.compilationRequired = true;
}
@@ -79,7 +80,7 @@ public class CompilationResultImpl implements CompilationResult {
if ( errors != null ) {
throw new ClassNotFoundException(className);
}
- return this.classLoader.loadClass(className);
+ return this.classLoaderWriter.getClassLoader().loadClass(className);
}
/**
diff --git a/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java b/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java
index ddf9070..2d7b6d9 100644
--- a/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java
+++ b/src/main/java/org/apache/sling/commons/compiler/impl/EclipseJavaCompiler.java
@@ -29,10 +29,8 @@ import java.util.Map;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
import org.apache.sling.commons.compiler.CompilationResult;
import org.apache.sling.commons.compiler.CompilationUnit;
import org.apache.sling.commons.compiler.JavaCompiler;
@@ -65,14 +63,9 @@ public class EclipseJavaCompiler implements JavaCompiler {
/** Logger instance */
private final Logger logger = LoggerFactory.getLogger(EclipseJavaCompiler.class);
- @Reference(policy=ReferencePolicy.DYNAMIC)
+ @Reference
private ClassLoaderWriter classLoaderWriter;
- @Reference(policy=ReferencePolicy.DYNAMIC)
- private DynamicClassLoaderManager dynamicClassLoaderManager;
-
- private ClassLoader classLoader;
-
/** the static problem factory */
private IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
@@ -80,52 +73,15 @@ public class EclipseJavaCompiler implements JavaCompiler {
private final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
/**
- * Bind the class load provider.
- * @param repositoryClassLoaderProvider the new provider
- */
- protected void bindDynamicClassLoaderManager(final DynamicClassLoaderManager rclp) {
- if ( this.classLoader != null ) {
- this.ungetClassLoader();
- }
- this.getClassLoader(rclp);
- }
-
- /**
- * Unbind the class loader provider.
- * @param repositoryClassLoaderProvider the old provider
- */
- protected void unbindDynamicClassLoaderManager(final DynamicClassLoaderManager rclp) {
- if ( this.dynamicClassLoaderManager == rclp ) {
- this.ungetClassLoader();
- }
- }
-
- /**
- * Get the commons dynamic class loader
- */
- private void getClassLoader(final DynamicClassLoaderManager rclp) {
- this.dynamicClassLoaderManager = rclp;
- this.classLoader = rclp.getDynamicClassLoader();
- }
-
- /**
- * Unget the commons dynamic class loader
- */
- private void ungetClassLoader() {
- this.classLoader = null;
- this.dynamicClassLoaderManager = null;
- }
-
- /**
* Get the classloader for the compilation.
*/
- private ClassLoader getClassLoader(final Options options) {
+ private ClassLoader getClassLoader(final Options options, final ClassLoaderWriter classLoaderWriter) {
final ClassLoader loader;
if ( options.get(Options.KEY_CLASS_LOADER) != null ) {
loader = (ClassLoader)options.get(Options.KEY_CLASS_LOADER);
} else if ( options.get(Options.KEY_ADDITIONAL_CLASS_LOADER) != null ) {
final ClassLoader additionalClassLoader = (ClassLoader)options.get(Options.KEY_ADDITIONAL_CLASS_LOADER);
- loader = new ClassLoader(this.classLoader) {
+ loader = new ClassLoader(classLoaderWriter.getClassLoader()) {
protected Class<?> findClass(String name)
throws ClassNotFoundException {
return additionalClassLoader.loadClass(name);
@@ -136,7 +92,7 @@ public class EclipseJavaCompiler implements JavaCompiler {
}
};
} else {
- loader = this.classLoader;
+ loader = classLoaderWriter.getClassLoader();
}
return loader;
}
@@ -197,14 +153,14 @@ public class EclipseJavaCompiler implements JavaCompiler {
final Options options = (compileOptions != null ? compileOptions : EMPTY_OPTIONS);
// get classloader and classloader writer
- final ClassLoader loader = this.getClassLoader(options);
- if ( loader == null ) {
- return new CompilationResultImpl("Class loader for compilation is not available.");
- }
final ClassLoaderWriter writer = this.getClassLoaderWriter(options);
if ( writer == null ) {
return new CompilationResultImpl("Class loader writer for compilation is not available.");
}
+ final ClassLoader loader = this.getClassLoader(options, writer);
+ if ( loader == null ) {
+ return new CompilationResultImpl("Class loader for compilation is not available.");
+ }
// check sources for compilation
boolean needsCompilation = isForceCompilation(options);
@@ -218,7 +174,7 @@ public class EclipseJavaCompiler implements JavaCompiler {
}
if ( !needsCompilation ) {
logger.debug("All source files are recent - no compilation required.");
- return new CompilationResultImpl(loader);
+ return new CompilationResultImpl(writer);
}
// delete old class files
@@ -248,7 +204,7 @@ public class EclipseJavaCompiler implements JavaCompiler {
logger.debug("Compiling with settings {}.", settings);
// create the result
- final CompilationResultImpl result = new CompilationResultImpl(isIgnoreWarnings(options), loader);
+ final CompilationResultImpl result = new CompilationResultImpl(isIgnoreWarnings(options), writer);
// create the context
final CompileContext context = new CompileContext(units, result, writer, loader);
diff --git a/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java b/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java
new file mode 100644
index 0000000..ace970a
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/compiler/impl/IsolatedClassLoader.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.sling.commons.compiler.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
+
+
+/**
+ * The <code>IsolatedClassLoader</code> class loads classes through
+ * the class loader writer
+ */
+public final class IsolatedClassLoader
+ extends SecureClassLoader {
+
+ private final ClassLoaderWriter classLoaderWriter;
+
+ public IsolatedClassLoader(final ClassLoader parent,
+ final ClassLoaderWriter classLoaderWriter) {
+ super(parent);
+ this.classLoaderWriter = classLoaderWriter;
+ }
+
+
+ //---------- Class loader overwrites -------------------------------------
+
+ /**
+ * Loads the class from this <code>ClassLoader</class>. If the
+ * class does not exist in this one, we check the parent. Please
+ * note that this is the exact opposite of the
+ * <code>ClassLoader</code> spec. We use it to work around
+ * inconsistent class loaders from third party vendors.
+ *
+ * @param name the name of the class
+ * @param resolve if <code>true</code> then resolve the class
+ * @return the resulting <code>Class</code> object
+ * @exception ClassNotFoundException if the class could not be found
+ */
+ public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ // First check if it's already loaded
+ Class<?> clazz = findLoadedClass(name);
+
+ if (clazz == null) {
+
+ try {
+ clazz = findClass(name);
+ } catch (final ClassNotFoundException cnfe) {
+ final ClassLoader parent = getParent();
+ if (parent != null) {
+ // Ask to parent ClassLoader (can also throw a CNFE).
+ clazz = parent.loadClass(name);
+ } else {
+ // Propagate exception
+ throw cnfe;
+ }
+ }
+ }
+
+ if (resolve) {
+ resolveClass(clazz);
+ }
+
+ return clazz;
+ }
+
+ /**
+ * Finds and loads the class with the specified name from the class path.
+ *
+ * @param name the name of the class
+ * @return the resulting class
+ *
+ * @throws ClassNotFoundException If the named class could not be found or
+ * if this class loader has already been destroyed.
+ */
+ protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ try {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Class<?>>() {
+
+ public Class<?> run() throws ClassNotFoundException {
+ return findClassPrivileged(name);
+ }
+ });
+ } catch (final java.security.PrivilegedActionException pae) {
+ throw (ClassNotFoundException) pae.getException();
+ }
+ }
+
+ /**
+ * Tries to find the class in the class path from within a
+ * <code>PrivilegedAction</code>. Throws <code>ClassNotFoundException</code>
+ * if no class can be found for the name.
+ *
+ * @param name the name of the class
+ *
+ * @return the resulting class
+ *
+ * @throws ClassNotFoundException if the class could not be found
+ * @throws NullPointerException If this class loader has already been
+ * destroyed.
+ */
+ private Class<?> findClassPrivileged(final String name) throws ClassNotFoundException {
+ // prepare the name of the class
+ final String path = "/" + name.replace('.', '/') + ".class";
+ InputStream is = null;
+ try {
+ is = this.classLoaderWriter.getInputStream(path);
+ final Class<?> c = defineClass(name, is);
+ if (c == null) {
+ throw new ClassNotFoundException(name);
+ }
+ return c;
+ } catch ( final ClassNotFoundException cnfe) {
+ throw cnfe;
+ } catch (final Throwable t) {
+ throw new ClassNotFoundException(name, t);
+ }
+ }
+
+ /**
+ * Defines a class getting the bytes for the class from the resource
+ *
+ * @param name The fully qualified class name
+ * @param is The resource to obtain the class bytes from
+ *
+ * @throws IOException If a problem occurrs reading the class bytes from
+ * the resource.
+ * @throws ClassFormatError If the class bytes read from the resource are
+ * not a valid class.
+ */
+ private Class<?> defineClass(final String name, final InputStream is)
+ throws IOException {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final byte[] buffer = new byte[2048];
+ int l;
+ while ( ( l = is.read(buffer)) >= 0 ) {
+ baos.write(buffer, 0, l);
+ }
+ final byte[] data = baos.toByteArray();
+ return defineClass(name, data, 0, data.length);
+ }
+}
diff --git a/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java b/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java
index c409ca0..ac5f0b5 100644
--- a/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java
+++ b/src/test/java/org/apache/sling/commons/compiler/impl/CompilerJava5Test.java
@@ -113,4 +113,11 @@ public class CompilerJava5Test extends TestCase
public boolean rename(String oldPath, String newPath) {
return false;
}
+
+ /**
+ * @see org.apache.sling.commons.classloader.ClassLoaderWriter#getClassLoader()
+ */
+ public ClassLoader getClassLoader() {
+ return null;
+ }
}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.