Skip to content

Commit

Permalink
LDEV-5063 - change visibility to PhysicalClassloader to allow loading…
Browse files Browse the repository at this point in the history
… Proxy classes from string
  • Loading branch information
michaeloffner committed Aug 19, 2024
1 parent 6a2c1c0 commit 6021cb9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
51 changes: 43 additions & 8 deletions core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.felix.framework.BundleWiringImpl.BundleClassLoader;

import lucee.commons.digest.HashUtil;
import lucee.commons.io.CharsetUtil;
import lucee.commons.io.IOUtil;
Expand Down Expand Up @@ -68,7 +70,7 @@ public final class PhysicalClassLoader extends URLClassLoader implements Extenda

private Resource directory;
private ConfigPro config;
private final ClassLoader parent;
private final ClassLoader addionalClassLoader;
private final Collection<Resource> resources;

private Map<String, String> loadedClasses = new ConcurrentHashMap<String, String>();
Expand Down Expand Up @@ -105,7 +107,7 @@ public static PhysicalClassLoader getPhysicalClassLoader(Config c, Resource dire
synchronized (SystemUtil.createToken("PhysicalClassLoader", key)) {
rpccl = reload ? null : classLoaders.get(key);
if (rpccl == null) {
classLoaders.put(key, rpccl = new PhysicalClassLoader(c, new ArrayList<Resource>(), directory, SystemUtil.getCombinedClassLoader(), null, false));
classLoaders.put(key, rpccl = new PhysicalClassLoader(c, new ArrayList<Resource>(), directory, SystemUtil.getCombinedClassLoader(), null, null, false));
}
}
}
Expand All @@ -130,19 +132,36 @@ public static PhysicalClassLoader getRPCClassLoader(Config c, JavaSettings js, b
}
Resource dir = storeResourceMeta(c, key, js, resources);
// (Config config, String key, JavaSettings js, Collection<Resource> _resources)
classLoaders.put(key, rpccl = new PhysicalClassLoader(c, resources, dir, SystemUtil.getCombinedClassLoader(), null, true));
classLoaders.put(key, rpccl = new PhysicalClassLoader(c, resources, dir, SystemUtil.getCombinedClassLoader(), null, null, true));
}
}
}
return rpccl;
}

public static PhysicalClassLoader getRPCClassLoader(Config c, BundleClassLoader bcl, boolean reload) throws IOException {
String key = HashUtil.create64BitHashAsString(bcl + "");
PhysicalClassLoader rpccl = reload ? null : classLoaders.get(key);
if (rpccl == null) {
synchronized (SystemUtil.createToken("PhysicalClassLoader", key)) {
rpccl = reload ? null : classLoaders.get(key);
if (rpccl == null) {
Resource dir = c.getClassDirectory().getRealResource("RPC/" + key);
if (!dir.exists()) ResourceUtil.createDirectoryEL(dir, true);
// (Config config, String key, JavaSettings js, Collection<Resource> _resources)
classLoaders.put(key, rpccl = new PhysicalClassLoader(c, new ArrayList<Resource>(), dir, SystemUtil.getCombinedClassLoader(), bcl, null, true));
}
}
}
return rpccl;
}

private PhysicalClassLoader(Config c, List<Resource> resources, Resource directory, ClassLoader parentClassLoader, PageSourcePool pageSourcePool, boolean rpc)
throws IOException {
private PhysicalClassLoader(Config c, List<Resource> resources, Resource directory, ClassLoader parentClassLoader, ClassLoader addionalClassLoader,
PageSourcePool pageSourcePool, boolean rpc) throws IOException {
super(doURLs(resources), parentClassLoader == null ? (parentClassLoader = SystemUtil.getCombinedClassLoader()) : parentClassLoader);
this.resources = resources;
config = (ConfigPro) c;
parent = parentClassLoader;
this.addionalClassLoader = addionalClassLoader;

this.pageSourcePool = pageSourcePool;
// ClassLoader resCL = parent!=null?parent:config.getResourceClassLoader(null);
Expand Down Expand Up @@ -175,13 +194,20 @@ private Class<?> loadClass(String name, boolean resolve, boolean loadFromFS) thr
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
// for (ClassLoader p: parents) {
try {
c = super.loadClass(name, resolve);
// break;
}
catch (Exception e) {
}

if (addionalClassLoader != null) {
try {
c = addionalClassLoader.loadClass(name);
}
catch (Exception e) {
}
}

// }
if (c == null) {
if (loadFromFS) c = findClass(name);
Expand All @@ -201,6 +227,14 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
catch (ClassNotFoundException cnfe) {
}

if (addionalClassLoader != null) {
try {
return addionalClassLoader.loadClass(name);
}
catch (ClassNotFoundException e) {
}
}

synchronized (SystemUtil.createToken("pcl", name)) {
Resource res = directory.getRealResource(name.replace('.', '/').concat(".class"));

Expand Down Expand Up @@ -428,4 +462,5 @@ public int compare(Resource l, Resource r) {
return l.getAbsolutePath().compareTo(r.getAbsolutePath());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.Map;
import java.util.Set;

import org.apache.felix.framework.BundleWiringImpl.BundleClassLoader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
Expand All @@ -51,7 +52,6 @@
import lucee.runtime.PageContext;
import lucee.runtime.PageContextImpl;
import lucee.runtime.config.ConfigWeb;
import lucee.runtime.engine.ThreadLocalPageContext;
import lucee.runtime.exp.PageException;
import lucee.runtime.op.Caster;
import lucee.runtime.op.JavaProxyUtilImpl;
Expand Down Expand Up @@ -231,6 +231,7 @@ public static Object createProxy(Object defaultValue, PageContext pc, Component
public static Object createProxy(PageContext pc, final Component cfc, Class extendz, Class... interfaces) throws PageException, IOException {
PageContextImpl pci = (PageContextImpl) pc;
PhysicalClassLoader pcl = getRPCClassLoaderFromClasses(pc, extendz, interfaces);

if (pcl == null) pcl = (PhysicalClassLoader) pci.getRPCClassLoader(false);

if (extendz == null) extendz = Object.class;
Expand Down Expand Up @@ -433,7 +434,7 @@ public static Object createProxy(PageContext pc, final Component cfc, Class exte
* // adapter.returnValue(); adapter.endMethod(); }
*/

private static PhysicalClassLoader getRPCClassLoaderFromClasses(PageContext pc, Class extendz, Class... interfaces) {
private static PhysicalClassLoader getRPCClassLoaderFromClasses(PageContext pc, Class extendz, Class... interfaces) throws IOException {
// extends and implement need to come from the same parent classloader
PhysicalClassLoader pcl = null;
if (extendz != null) {
Expand All @@ -450,13 +451,16 @@ private static PhysicalClassLoader getRPCClassLoaderFromClasses(PageContext pc,
return null;
}

public static PhysicalClassLoader getRPCClassLoaderFromClass(PageContext pc, Class clazz) {
public static PhysicalClassLoader getRPCClassLoaderFromClass(PageContext pc, Class clazz) throws IOException {
ClassLoader cl = clazz.getClassLoader();
pc = ThreadLocalPageContext.get(pc);
if (cl != null) {
if (cl instanceof PhysicalClassLoader) {
return ((PhysicalClassLoader) cl);
}
else if (cl instanceof BundleClassLoader) {
return PhysicalClassLoader.getRPCClassLoader(pc.getConfig(), (BundleClassLoader) cl, false);
}

}
return null;
}
Expand Down

0 comments on commit 6021cb9

Please sign in to comment.