diff --git a/core/src/main/java/lucee/commons/io/SystemUtil.java b/core/src/main/java/lucee/commons/io/SystemUtil.java index 28f27a248e..ada33705bc 100644 --- a/core/src/main/java/lucee/commons/io/SystemUtil.java +++ b/core/src/main/java/lucee/commons/io/SystemUtil.java @@ -1621,7 +1621,9 @@ public static List getClassLoaderContext(boolean unique, StringBuil // check ClassLoader if (cl == null) continue; - if (cl instanceof PhysicalClassLoader) continue; + if (cl instanceof PhysicalClassLoader) { + if (!((PhysicalClassLoader) cl).isRPC()) continue; + } if (cl instanceof ArchiveClassLoader) continue; if (cl instanceof MemoryClassLoader) continue; @@ -1639,6 +1641,7 @@ public static List getClassLoaderContext(boolean unique, StringBuil } last = ref.context[i]; } + return context; } diff --git a/core/src/main/java/lucee/commons/io/res/util/ResourceClassLoader.java b/core/src/main/java/lucee/commons/io/res/util/ResourceClassLoader.java deleted file mode 100755 index bfdc69ea74..0000000000 --- a/core/src/main/java/lucee/commons/io/res/util/ResourceClassLoader.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * - * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - **/ -package lucee.commons.io.res.util; - -import java.io.Closeable; -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import lucee.commons.digest.HashUtil; -import lucee.commons.io.res.Resource; -import lucee.commons.io.res.type.file.FileResource; -import lucee.runtime.exp.PageException; - -/** - * Classloader that load classes from resources - */ -public class ResourceClassLoader extends URLClassLoader implements Closeable { - private static Map classloaders = new ConcurrentHashMap<>(); - - private final Collection resources; - - private final String id; - private static RC rc = new RC(); - static { - boolean res = registerAsParallelCapable(); - } - - public static ResourceClassLoader getInstance(Resource[] resources, ClassLoader parent) throws IOException { - List list = new ArrayList(); - for (Resource r: resources) { - if (r != null) list.add(r); - } - java.util.Collections.sort(list, rc); - return getInstance(list, parent); - } - - public static ResourceClassLoader getInstance(Collection resources, ClassLoader parent) throws IOException { - List list = new ArrayList(); - for (Resource r: resources) { - if (r != null) list.add(r); - } - java.util.Collections.sort(list, rc); - return getInstance(list, parent); - } - - private static ResourceClassLoader getInstance(List resourcesSorted, ClassLoader parent) throws IOException { - StringBuilder sb = new StringBuilder(); - for (Resource r: resourcesSorted) { - if (r != null) sb.append(r.getAbsolutePath()).append(';'); - } - String id = HashUtil.create64BitHashAsString(sb); - ResourceClassLoader rcl = classloaders.get(id); - if (rcl == null) { - rcl = new ResourceClassLoader(resourcesSorted, parent, id); - classloaders.put(id, rcl); - } - return rcl; - } - - private ResourceClassLoader(List resources, ClassLoader parent, String id) throws IOException { - super(doURLs(resources), parent); - this.resources = resources; - this.id = id; - } - - private ResourceClassLoader(ClassLoader parent) { - super(new URL[0], parent); - this.resources = new ArrayList(); - this.id = "orphan"; - } - - /** - * @return the resources - */ - public Resource[] getResources() { - return resources.toArray(new Resource[resources.size()]); - } - - public boolean isEmpty() { - return resources.isEmpty(); - } - - public static URL[] doURLs(Collection reses) throws IOException { - List list = new ArrayList(); - for (Resource r: reses) { - if (r.isDirectory() || "jar".equalsIgnoreCase(ResourceUtil.getExtension(r, null))) list.add(doURL(r)); - } - return list.toArray(new URL[list.size()]); - } - - /** - * translate resources to url Objects - * - * @param reses - * @return - * @throws PageException - */ - public static URL[] doURLs(Resource[] reses) throws IOException { - List list = new ArrayList(); - for (int i = 0; i < reses.length; i++) { - if (reses[i].isDirectory() || "jar".equalsIgnoreCase(ResourceUtil.getExtension(reses[i], null))) list.add(doURL(reses[i])); - } - return list.toArray(new URL[list.size()]); - - } - - private static URL doURL(Resource res) throws IOException { - if (!(res instanceof FileResource)) { - return ResourceUtil.toFile(res).toURL(); - } - return ((FileResource) res).toURL(); - } - - @Override - public void close() { - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - public String hash() { - return id; - } - - private static class RC implements Comparator { - - @Override - public int compare(Resource l, Resource r) { - return l.getAbsolutePath().compareTo(r.getAbsolutePath()); - } - } -} \ No newline at end of file diff --git a/core/src/main/java/lucee/commons/lang/ClassUtil.java b/core/src/main/java/lucee/commons/lang/ClassUtil.java index 13dcba83bc..db7555af92 100644 --- a/core/src/main/java/lucee/commons/lang/ClassUtil.java +++ b/core/src/main/java/lucee/commons/lang/ClassUtil.java @@ -45,7 +45,6 @@ import lucee.commons.io.IOUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.res.Resource; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.runtime.PageContext; import lucee.runtime.PageContextImpl; import lucee.runtime.config.Config; @@ -53,7 +52,6 @@ import lucee.runtime.config.Identification; import lucee.runtime.engine.ThreadLocalPageContext; import lucee.runtime.exp.PageException; -import lucee.runtime.listener.JavaSettingsImpl; import lucee.runtime.op.Caster; import lucee.runtime.osgi.OSGiUtil; import lucee.runtime.osgi.OSGiUtil.BundleDefinition; @@ -313,11 +311,6 @@ public static Class loadClass(ClassLoader cl, String className, Class defaultVal private static Class loadClass(ClassLoader cl, String className, Class defaultValue, Set exceptions) { if (cl != null) { - // TODO do not produce a resource classloader in the first place if there are no resources - if (cl instanceof ResourceClassLoader && ((ResourceClassLoader) cl).isEmpty()) { - ClassLoader p = ((ResourceClassLoader) cl).getParent(); - if (p != null) cl = p; - } Class clazz = _loadClass(new ClassLoaderBasedClassLoading(cl), className, defaultValue, exceptions); if (clazz != null) return clazz; } @@ -1035,10 +1028,9 @@ public static ClassLoader getClassLoader(PageContext pc, Class clazz) throws IOE if (pc instanceof PageContextImpl) { return ((PageContextImpl) pc).getClassLoader(); } - // NEXT this is wrong Config config = ThreadLocalPageContext.getConfig(); if (config instanceof ConfigPro) { - return ((JavaSettingsImpl) ((ConfigPro) config).getJavaSettings()).getClassLoader(false); + return ((ConfigPro) config).getRPCClassLoader(false, null); } return new lucee.commons.lang.ClassLoaderHelper().getClass().getClassLoader(); } diff --git a/core/src/main/java/lucee/commons/lang/ExtendableClassLoader.java b/core/src/main/java/lucee/commons/lang/ExtendableClassLoader.java index 8386e189f6..6a2515231a 100644 --- a/core/src/main/java/lucee/commons/lang/ExtendableClassLoader.java +++ b/core/src/main/java/lucee/commons/lang/ExtendableClassLoader.java @@ -20,15 +20,7 @@ import java.lang.instrument.UnmodifiableClassException; -public abstract class ExtendableClassLoader extends ClassLoader { - - public ExtendableClassLoader() { - super(); - } - - public ExtendableClassLoader(ClassLoader parent) { - super(parent); - } +public interface ExtendableClassLoader { /** * allow to define a new Class with help of the bytecode passed to the method diff --git a/core/src/main/java/lucee/commons/lang/MemoryClassLoader.java b/core/src/main/java/lucee/commons/lang/MemoryClassLoader.java index e70df8575b..1059d5ca47 100644 --- a/core/src/main/java/lucee/commons/lang/MemoryClassLoader.java +++ b/core/src/main/java/lucee/commons/lang/MemoryClassLoader.java @@ -27,7 +27,7 @@ /** * ClassLoader that loads classes in memory that are not stored somewhere physically */ -public final class MemoryClassLoader extends ExtendableClassLoader { +public final class MemoryClassLoader extends ClassLoader implements ExtendableClassLoader { static { boolean res = registerAsParallelCapable(); } diff --git a/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java b/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java index 62a545fccf..aef7a0a6d8 100644 --- a/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java +++ b/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java @@ -22,43 +22,63 @@ import java.io.IOException; import java.io.InputStream; import java.lang.instrument.UnmodifiableClassException; -import java.lang.ref.SoftReference; import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import lucee.commons.digest.HashUtil; +import lucee.commons.io.CharsetUtil; import lucee.commons.io.IOUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.log.LogUtil; import lucee.commons.io.res.Resource; -import lucee.commons.io.res.util.ResourceClassLoader; +import lucee.commons.io.res.type.file.FileResource; +import lucee.commons.io.res.util.ResourceUtil; import lucee.runtime.PageSourcePool; import lucee.runtime.config.Config; import lucee.runtime.config.ConfigPro; +import lucee.runtime.converter.ConverterException; +import lucee.runtime.converter.JSONConverter; +import lucee.runtime.converter.JSONDateFormat; import lucee.runtime.exp.ApplicationException; +import lucee.runtime.listener.JavaSettings; +import lucee.runtime.listener.JavaSettingsImpl; +import lucee.runtime.listener.SerializationSettings; +import lucee.runtime.type.Struct; +import lucee.runtime.type.StructImpl; +import lucee.runtime.type.util.KeyConstants; import lucee.transformer.bytecode.util.ClassRenamer; /** * Directory ClassLoader */ -public final class PhysicalClassLoader extends ExtendableClassLoader { +public final class PhysicalClassLoader extends URLClassLoader implements ExtendableClassLoader { static { boolean res = registerAsParallelCapable(); } + private static RC rc = new RC(); + + private static Map classLoaders = new ConcurrentHashMap<>(); + private Resource directory; private ConfigPro config; - private final ClassLoader[] parents; + private final ClassLoader parent; + private final Collection resources; private Map loadedClasses = new ConcurrentHashMap(); private Map allLoadedClasses = new ConcurrentHashMap(); // this includes all renames private Map unavaiClasses = new ConcurrentHashMap(); - private Map> customCLs; private PageSourcePool pageSourcePool; + private boolean rpc; + private static long counter = 0L; private static long _start = 0L; private static String start = Long.toString(_start, Character.MAX_RADIX); @@ -76,41 +96,67 @@ public static String uid() { } } - /** - * Constructor of the class - * - * @param directory - * @param parent - * @throws IOException - */ - public PhysicalClassLoader(Config c, Resource directory, PageSourcePool pageSourcePool) throws IOException { - this(c, directory, (ClassLoader) null, true, pageSourcePool); + public static PhysicalClassLoader getPhysicalClassLoader(Config c, Resource directory, boolean reload) throws IOException { + + String key = HashUtil.create64BitHashAsString(directory.getAbsolutePath()); + + PhysicalClassLoader rpccl = reload ? null : classLoaders.get(key); + if (rpccl == null) { + synchronized (SystemUtil.createToken("PhysicalClassLoader", key)) { + rpccl = reload ? null : classLoaders.get(key); + if (rpccl == null) { + classLoaders.put(key, rpccl = new PhysicalClassLoader(c, new ArrayList(), directory, SystemUtil.getCombinedClassLoader(), null, false)); + } + } + } + return rpccl; + } + + public static PhysicalClassLoader getRPCClassLoader(Config c, JavaSettings js, boolean reload) throws IOException { + + String key = js == null ? "orphan" : ((JavaSettingsImpl) js).id(); + + PhysicalClassLoader rpccl = reload ? null : classLoaders.get(key); + if (rpccl == null) { + synchronized (SystemUtil.createToken("PhysicalClassLoader", key)) { + rpccl = reload ? null : classLoaders.get(key); + if (rpccl == null) { + List resources; + if (js == null) { + resources = new ArrayList(); + } + else { + resources = toSortedList(JavaSettingsImpl.getAllResources(js)); + } + Resource dir = storeResourceMeta(c, key, js, resources); + // (Config config, String key, JavaSettings js, Collection _resources) + classLoaders.put(key, rpccl = new PhysicalClassLoader(c, resources, dir, SystemUtil.getCombinedClassLoader(), null, true)); + } + } + } + return rpccl; } - public PhysicalClassLoader(Config c, Resource directory, ClassLoader parentClassLoader, boolean includeCoreCL, PageSourcePool pageSourcePool) throws IOException { - super(parentClassLoader == null ? c.getClassLoader() : parentClassLoader); + private PhysicalClassLoader(Config c, List resources, Resource directory, ClassLoader parentClassLoader, PageSourcePool pageSourcePool, boolean rpc) + throws IOException { + super(doURLs(resources), parentClassLoader == null ? (parentClassLoader = SystemUtil.getCombinedClassLoader()) : parentClassLoader); + this.resources = resources; config = (ConfigPro) c; + parent = parentClassLoader; this.pageSourcePool = pageSourcePool; // ClassLoader resCL = parent!=null?parent:config.getResourceClassLoader(null); - List tmp = new ArrayList(); - if (parentClassLoader == null) { - ResourceClassLoader _cl = config.getResourceClassLoader(null); - if (_cl != null) tmp.add(_cl); - } - else { - tmp.add(parentClassLoader); - } - - if (includeCoreCL) tmp.add(config.getClassLoaderCore()); - parents = tmp.toArray(new ClassLoader[tmp.size()]); - // check directory if (!directory.exists()) directory.mkdirs(); if (!directory.isDirectory()) throw new IOException("Resource [" + directory + "] is not a directory"); if (!directory.canRead()) throw new IOException("Access denied to [" + directory + "] directory"); this.directory = directory; + this.rpc = rpc; + } + + public boolean isRPC() { + return rpc; } @Override @@ -129,14 +175,14 @@ 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 = p.loadClass(name); - break; - } - catch (Exception e) { - } + // for (ClassLoader p: parents) { + try { + c = super.loadClass(name, resolve); + // break; + } + catch (Exception e) { } + // } if (c == null) { if (loadFromFS) c = findClass(name); else throw new ClassNotFoundException(name); @@ -147,7 +193,14 @@ private Class loadClass(String name, boolean resolve, boolean loadFromFS) thr } @Override - protected Class findClass(String name) throws ClassNotFoundException {// if(name.indexOf("sub")!=-1)print.ds(name); + protected Class findClass(String name) throws ClassNotFoundException { + + try { + return super.findClass(name); + } + catch (ClassNotFoundException cnfe) { + } + synchronized (SystemUtil.createToken("pcl", name)) { Resource res = directory.getRealResource(name.replace('.', '/').concat(".class")); @@ -212,6 +265,14 @@ public URL getResource(String name) { return null; } + public Resource[] getJarResources() { + return resources.toArray(new Resource[resources.size()]); + } + + public boolean hasJarResources() { + return resources.isEmpty(); + } + public int getSize(boolean includeAllRenames) { return includeAllRenames ? allLoadedClasses.size() : loadedClasses.size(); } @@ -274,6 +335,26 @@ public void clear(boolean clearPagePool) { this.unavaiClasses.clear(); } + private static Resource storeResourceMeta(Config config, String key, JavaSettings js, Collection _resources) throws IOException { + Resource dir = config.getClassDirectory().getRealResource("RPC/" + key); + if (!dir.exists()) { + ResourceUtil.createDirectoryEL(dir, true); + Resource file = dir.getRealResource("classloader-resources.json"); + Struct root = new StructImpl(); + root.setEL(KeyConstants._resources, _resources); + JSONConverter json = new JSONConverter(true, CharsetUtil.UTF8, JSONDateFormat.PATTERN_CF, false); + try { + String str = json.serialize(null, root, SerializationSettings.SERIALIZE_AS_COLUMN, null); + IOUtil.write(file, str, CharsetUtil.UTF8, false); + } + catch (ConverterException e) { + throw ExceptionUtil.toIOException(e); + } + + } + return dir; + } + /** * removes memory based appendix from class name, for example it translates * [test.test_cfc$sub2$cf$5] to [test.test_cfc$sub2$cf] @@ -303,4 +384,48 @@ public void finalize() throws Throwable { super.finalize(); } + public static List toSortedList(Collection resources) { + List list = new ArrayList(); + if (resources != null) { + for (Resource r: resources) { + if (r != null) list.add(r); + } + } + java.util.Collections.sort(list, rc); + return list; + } + + public static List toSortedList(Resource[] resources) { + List list = new ArrayList(); + if (resources != null) { + for (Resource r: resources) { + if (r != null) list.add(r); + } + } + java.util.Collections.sort(list, rc); + return list; + } + + private static URL[] doURLs(Collection reses) throws IOException { + List list = new ArrayList(); + for (Resource r: reses) { + if (r.isDirectory() || "jar".equalsIgnoreCase(ResourceUtil.getExtension(r, null))) list.add(doURL(r)); + } + return list.toArray(new URL[list.size()]); + } + + private static URL doURL(Resource res) throws IOException { + if (!(res instanceof FileResource)) { + return ResourceUtil.toFile(res).toURL(); + } + return ((FileResource) res).toURL(); + } + + private static class RC implements Comparator { + + @Override + public int compare(Resource l, Resource r) { + return l.getAbsolutePath().compareTo(r.getAbsolutePath()); + } + } } diff --git a/core/src/main/java/lucee/runtime/MappingImpl.java b/core/src/main/java/lucee/runtime/MappingImpl.java index 717993b682..6c8c2d3c2c 100755 --- a/core/src/main/java/lucee/runtime/MappingImpl.java +++ b/core/src/main/java/lucee/runtime/MappingImpl.java @@ -23,7 +23,6 @@ import java.io.Serializable; import java.lang.instrument.UnmodifiableClassException; import java.lang.ref.SoftReference; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -72,7 +71,7 @@ public final class MappingImpl implements Mapping { private final int inspectTemplateAutoIntervalFast; private boolean physicalFirst; - private transient Map loaders = new HashMap<>(); + // private transient Map loaders = new HashMap<>(); private Resource archive; private final Config config; @@ -253,25 +252,27 @@ public Class loadClass(String className) { } private Class loadClass(String className, byte[] code) throws IOException, ClassNotFoundException { - - PhysicalClassLoaderReference pclr = loaders.get(className); - PhysicalClassLoader pcl = pclr == null ? null : pclr.get(); - if (pcl == null || code != null) {// || pcl.getSize(true) > 3 - if (pcl != null) { - pcl.clear(); - } - pcl = new PhysicalClassLoader(config, getClassRootDirectory(), pageSourcePool); - synchronized (loaders) { - loaders.put(className, new PhysicalClassLoaderReference(pcl)); - } - } + PhysicalClassLoader pcl = PhysicalClassLoader.getPhysicalClassLoader(config, getClassRootDirectory(), false); + /* + * PhysicalClassLoaderReference pclr = loaders.get(className); PhysicalClassLoader pcl = pclr == + * null ? null : pclr.get(); if (pcl == null || code != null) {// || pcl.getSize(true) > 3 if (pcl + * != null) { pcl.clear(); } pcl = PhysicalClassLoader.getPhysicalClassLoader(config, + * getClassRootDirectory(), true); synchronized (loaders) { loaders.put(className, new + * PhysicalClassLoaderReference(pcl)); } } + */ if (code != null) { try { return pcl.loadClass(className, code); } catch (UnmodifiableClassException e) { - throw ExceptionUtil.toIOException(e); + pcl = PhysicalClassLoader.getPhysicalClassLoader(config, getClassRootDirectory(), true); + try { + return pcl.loadClass(className, code); + } + catch (UnmodifiableClassException ex) { + throw ExceptionUtil.toIOException(ex); + } } } return pcl.loadClass(className); @@ -282,18 +283,10 @@ public void cleanLoaders() { } public void clear(String className) { - PhysicalClassLoaderReference ref = loaders.remove(className); - PhysicalClassLoader pcl; - if (ref != null) { - pcl = ref.get(); - if (pcl != null) { - pcl.clear(false); - } - } - } - - public int getSize() { - return loaders.size(); + /* + * PhysicalClassLoaderReference ref = loaders.remove(className); PhysicalClassLoader pcl; if (ref != + * null) { pcl = ref.get(); if (pcl != null) { pcl.clear(false); } } + */ } @Override diff --git a/core/src/main/java/lucee/runtime/PageContextImpl.java b/core/src/main/java/lucee/runtime/PageContextImpl.java index b0a16e2746..9160c35be7 100644 --- a/core/src/main/java/lucee/runtime/PageContextImpl.java +++ b/core/src/main/java/lucee/runtime/PageContextImpl.java @@ -66,7 +66,6 @@ import lucee.commons.io.log.Log; import lucee.commons.io.log.LogUtil; import lucee.commons.io.res.Resource; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.lang.ClassException; import lucee.commons.lang.ClassUtil; import lucee.commons.lang.ExceptionUtil; @@ -3845,30 +3844,24 @@ public JavaSettings getJavaSettings() { return getApplicationContext().getJavaSettings(); } + public ClassLoader getRPCClassLoader(boolean reload) throws IOException { + return getRPCClassLoader(reload, (JavaSettings) null); + } + public ClassLoader getClassLoader() throws IOException { - return getClassLoader(null); + return getRPCClassLoader(false, (JavaSettings) null); } public ClassLoader getClassLoader(JavaSettings customJS) throws IOException { + return getRPCClassLoader(false, customJS); + } + + public ClassLoader getRPCClassLoader(boolean reload, JavaSettings customJS) throws IOException { JavaSettings js = getJavaSettings(); if (customJS != null) { js = JavaSettingsImpl.merge(config, js, customJS); } - return ((JavaSettingsImpl) js).getClassLoader(false); - } - - public ClassLoader getRPCClassLoader(boolean reload) throws IOException { - return getRPCClassLoader(reload, (JavaSettings) null); - } - - public ClassLoader getRPCClassLoader(boolean reload, JavaSettings customJS) throws IOException { - return ((ConfigPro) config).getRPCClassLoader(reload, (ResourceClassLoader) getClassLoader(customJS)); - - } - - public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException { - return ((ConfigPro) config).getRPCClassLoader(reload, parent); - + return ((ConfigPro) config).getRPCClassLoader(reload, js); } public void resetSession() { diff --git a/core/src/main/java/lucee/runtime/config/ConfigImpl.java b/core/src/main/java/lucee/runtime/config/ConfigImpl.java index 4966343d38..b9ab4b54e9 100755 --- a/core/src/main/java/lucee/runtime/config/ConfigImpl.java +++ b/core/src/main/java/lucee/runtime/config/ConfigImpl.java @@ -41,10 +41,8 @@ import org.osgi.framework.BundleException; import org.osgi.framework.Version; -import lucee.commons.digest.HashUtil; import lucee.commons.io.CharsetUtil; import lucee.commons.io.FileUtil; -import lucee.commons.io.IOUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.cache.Cache; import lucee.commons.io.log.Log; @@ -58,7 +56,6 @@ import lucee.commons.io.res.ResourcesImpl.ResourceProviderFactory; import lucee.commons.io.res.filter.ExtensionResourceFilter; import lucee.commons.io.res.type.compress.Compress; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.CharSet; import lucee.commons.lang.ClassException; @@ -89,9 +86,6 @@ import lucee.runtime.config.ConfigWebFactory.Path; import lucee.runtime.config.ConfigWebUtil.CacheElement; import lucee.runtime.config.gateway.GatewayMap; -import lucee.runtime.converter.ConverterException; -import lucee.runtime.converter.JSONConverter; -import lucee.runtime.converter.JSONDateFormat; import lucee.runtime.customtag.InitFile; import lucee.runtime.db.ClassDefinition; import lucee.runtime.db.DataSource; @@ -122,7 +116,6 @@ import lucee.runtime.listener.ApplicationListener; import lucee.runtime.listener.JavaSettings; import lucee.runtime.listener.JavaSettingsImpl; -import lucee.runtime.listener.SerializationSettings; import lucee.runtime.net.mail.Server; import lucee.runtime.net.proxy.ProxyData; import lucee.runtime.net.proxy.ProxyDataImpl; @@ -389,8 +382,6 @@ public abstract class ConfigImpl extends ConfigBase implements ConfigPro { private Map ormengines = new HashMap(); private ClassDefinition cdORMEngine; private ORMConfiguration ormConfig; - private ResourceClassLoader resourceCL; - private JavaSettings js; private ImportDefintion componentDefaultImport = new ImportDefintionImpl(Constants.DEFAULT_PACKAGE, "*"); private boolean componentLocalSearch = true; @@ -669,9 +660,14 @@ public int getQueryVarUsage() { @Override public ClassLoader getClassLoader() { - ResourceClassLoader rcl = getResourceClassLoader(null); - if (rcl != null) return rcl; - return new lucee.commons.lang.ClassLoaderHelper().getClass().getClassLoader(); + ClassLoader cl = null; + try { + cl = getRPCClassLoader(false); + } + catch (IOException e) { + } + if (cl != null) return cl; + return SystemUtil.getCombinedClassLoader(); } @@ -686,21 +682,6 @@ public ClassLoader getClassLoaderEnv() { public ClassLoader getClassLoaderCore() { return new lucee.commons.lang.ClassLoaderHelper().getClass().getClassLoader(); } - /* - * public ClassLoader getClassLoaderLoader() { return new TP().getClass().getClassLoader(); } - */ - - @Override - public ResourceClassLoader getResourceClassLoader() { - if (resourceCL == null) throw new RuntimeException("no RCL defined yet!"); - return resourceCL; - } - - @Override - public ResourceClassLoader getResourceClassLoader(ResourceClassLoader defaultValue) { - if (resourceCL == null) return defaultValue; - return resourceCL; - } @Override public Locale getLocale() { @@ -2260,38 +2241,12 @@ protected void setClientScopeDirSize(long clientScopeDirSize) { @Override public ClassLoader getRPCClassLoader(boolean reload) throws IOException { - return getRPCClassLoader(reload, null); + return PhysicalClassLoader.getRPCClassLoader(this, getJavaSettings(), reload); } @Override - public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException { - String key = parent.hash(); - PhysicalClassLoader rpccl = reload ? null : rpcClassLoaders.get(key); - if (rpccl == null) { - synchronized (key) { - rpccl = reload ? null : rpcClassLoaders.get(key); - if (rpccl == null) { - Resource dir = getClassDirectory().getRealResource("RPC/" + key); - if (!dir.exists()) { - ResourceUtil.createDirectoryEL(dir, true); - Resource file = dir.getRealResource("classloader-resources.json"); - Struct root = new StructImpl(); - root.setEL(KeyConstants._resources, parent.getResources()); - JSONConverter json = new JSONConverter(true, CharsetUtil.UTF8, JSONDateFormat.PATTERN_CF, false); - try { - String str = json.serialize(null, root, SerializationSettings.SERIALIZE_AS_COLUMN, null); - IOUtil.write(file, str, CharsetUtil.UTF8, false); - } - catch (ConverterException e) { - throw ExceptionUtil.toIOException(e); - } - - } - rpcClassLoaders.put(key, rpccl = new PhysicalClassLoader(this, dir, parent, false, null)); - } - } - } - return rpccl; + public ClassLoader getRPCClassLoader(boolean reload, JavaSettings js) throws IOException { + return PhysicalClassLoader.getRPCClassLoader(this, js != null ? js : getJavaSettings(), reload); } private static final Object dclt = new SerializableObject(); @@ -2305,24 +2260,13 @@ public PhysicalClassLoader getDirectClassLoader(boolean reload) throws IOExcepti if (!dir.exists()) { ResourceUtil.createDirectoryEL(dir, true); } - directClassLoader = new PhysicalClassLoader(this, dir, null); + directClassLoader = PhysicalClassLoader.getPhysicalClassLoader(this, dir, reload); } } } return directClassLoader; } - private String toKey(ClassLoader parent) { - if (parent == null) return "orphan"; - if (parent instanceof ResourceClassLoader) { - return ((ResourceClassLoader) parent).hash(); - } - - StringBuilder sb = new StringBuilder(); - sb.append(';').append(System.identityHashCode(parent)); - return HashUtil.create64BitHashAsString(sb.toString()); - } - public void resetRPCClassLoader() { rpcClassLoaders.clear(); } diff --git a/core/src/main/java/lucee/runtime/config/ConfigPro.java b/core/src/main/java/lucee/runtime/config/ConfigPro.java index a5d9c44398..dd600192f1 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigPro.java +++ b/core/src/main/java/lucee/runtime/config/ConfigPro.java @@ -15,7 +15,6 @@ import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourcesImpl.ResourceProviderFactory; import lucee.commons.io.res.type.compress.Compress; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.lang.CharSet; import lucee.commons.lang.ClassException; import lucee.commons.lang.PhysicalClassLoader; @@ -188,9 +187,7 @@ public interface ConfigPro extends Config { public boolean getTypeChecking(); - public ResourceClassLoader getResourceClassLoader(); - - public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException; + public ClassLoader getRPCClassLoader(boolean reload, JavaSettings js) throws IOException; public PageSource toPageSource(Mapping[] mappings, Resource res, PageSource defaultValue); @@ -339,8 +336,6 @@ public interface ConfigPro extends Config { */ public List loadLocalExtensions(boolean validate); - public ResourceClassLoader getResourceClassLoader(ResourceClassLoader defaultValue); - public Compress getCompressInstance(Resource zipFile, int format, boolean caseSensitive) throws IOException; public int getPasswordOrigin(); diff --git a/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java b/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java index eb2db80dc4..54d2580e0a 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java +++ b/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java @@ -13,7 +13,6 @@ import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourcesImpl.ResourceProviderFactory; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.lang.PhysicalClassLoader; import lucee.runtime.ai.AIEngineFactory; import lucee.runtime.ai.AIEnginePool; @@ -780,7 +779,7 @@ public lucee.runtime.config.ConfigServer getConfigServer(java.lang.String arg0, } @Override - public ClassLoader getRPCClassLoader(boolean arg0, ResourceClassLoader arg1) throws java.io.IOException { + public ClassLoader getRPCClassLoader(boolean arg0, JavaSettings arg1) throws java.io.IOException { return instance.getRPCClassLoader(arg0, arg1); } @@ -1161,11 +1160,6 @@ public boolean isMailSendPartial() { return instance.isMailSendPartial(); } - @Override - public lucee.commons.io.res.util.ResourceClassLoader getResourceClassLoader(lucee.commons.io.res.util.ResourceClassLoader arg0) { - return instance.getResourceClassLoader(arg0); - } - public lucee.runtime.config.ConfigServerImpl getConfigServerImpl() { if (instance instanceof MultiContextConfigWeb) return ((MultiContextConfigWeb) instance).getConfigServerImpl(); return ((SingleContextConfigWeb) instance).getConfigServerImpl(); @@ -1398,11 +1392,6 @@ public int getQueryVarUsage() { return instance.getQueryVarUsage(); } - @Override - public lucee.commons.io.res.util.ResourceClassLoader getResourceClassLoader() { - return instance.getResourceClassLoader(); - } - @Override public ResourceProviderFactory[] getResourceProviderFactories() { return instance.getResourceProviderFactories(); diff --git a/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java b/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java index 7fc1a3c5d3..6b3fdc0519 100644 --- a/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java +++ b/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java @@ -33,7 +33,6 @@ import lucee.commons.io.res.ResourcesImpl; import lucee.commons.io.res.ResourcesImpl.ResourceProviderFactory; import lucee.commons.io.res.type.compress.Compress; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.CharSet; import lucee.commons.lang.ClassException; @@ -294,16 +293,6 @@ public ClassLoader getClassLoaderCore() { return cs.getClassLoaderCore(); } - @Override - public ResourceClassLoader getResourceClassLoader() { - return cs.getResourceClassLoader(); - } - - @Override - public ResourceClassLoader getResourceClassLoader(ResourceClassLoader defaultValue) { - return cs.getResourceClassLoader(defaultValue); - } - @Override public Locale getLocale() { return cs.getLocale(); @@ -733,8 +722,8 @@ public ClassLoader getRPCClassLoader(boolean reload) throws IOException { } @Override - public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException { - return cs.getRPCClassLoader(reload, parent); + public ClassLoader getRPCClassLoader(boolean reload, JavaSettings js) throws IOException { + return cs.getRPCClassLoader(reload, js); } @Override diff --git a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java index 5ab350252c..11a1483860 100644 --- a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java +++ b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java @@ -28,11 +28,9 @@ import java.util.Map; import lucee.commons.digest.HashUtil; -import lucee.commons.io.SystemUtil; import lucee.commons.io.log.Log; import lucee.commons.io.log.LogUtil; import lucee.commons.io.res.Resource; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.PageContext; @@ -67,9 +65,6 @@ public class JavaSettingsImpl implements JavaSettings { private final int watchInterval; private final String[] watchedExtensions; private boolean hasBundlesTranslated; - // private Map classLoaders = new ConcurrentHashMap(); - private ResourceClassLoader classLoader; private Config config; private String id; @@ -86,7 +81,6 @@ private JavaSettingsImpl(String id, Config config, Collection poms, Collect this.reloadOnChange = reloadOnChange; this.watchInterval = watchInterval; this.watchedExtensions = watchedExtensions == null ? new String[] { "jar", "class" } : watchedExtensions; - // TODO needed? SystemExitScanner.validate(resources); } @@ -175,7 +169,6 @@ public static JavaSettings merge(Config config, JavaSettings l, JavaSettings r) ((ConfigPro) config).setJavaSettings(id, l); return l; } - js = new JavaSettingsImpl(id, config, mapPOMs.values(), mapOSGIs.values(), mapResources.values().toArray(new Resource[mapResources.size()]), mapBundles.values().toArray(new Resource[mapBundles.size()]), ri.loadCFMLClassPath, ri.reloadOnChange, ri.watchInterval, mapWatched.keySet().toArray(new String[mapWatched.size()])); @@ -188,6 +181,10 @@ public boolean hasPoms() { return poms != null && poms.size() > 0; } + public String id() { + return id; + } + public Collection getPoms() { return poms; } @@ -196,28 +193,20 @@ public boolean hasOSGis() { return osgis != null && osgis.size() > 0; } - public ResourceClassLoader getClassLoader(boolean reload) throws IOException { - if (classLoader == null || reload) { - ClassLoader parent = SystemUtil.getCombinedClassLoader(); - Collection allResources = getAllResources(null); - return classLoader = ResourceClassLoader.getInstance(allResources, parent); - } - return classLoader; + /* + * private ResourceClassLoader getClassLoader(boolean reload) throws IOException { if (classLoader + * == null || reload) { ClassLoader parent = SystemUtil.getCombinedClassLoader(); + * Collection allResources = getAllResources((ClassLoader) null); return classLoader = + * ResourceClassLoader.getInstance(allResources, parent); } return classLoader; } + */ + + public static Collection getAllResources(JavaSettings js) throws IOException { + return ((JavaSettingsImpl) js).getAllResources((ClassLoader) null); } public Collection getAllResources(ClassLoader parent) throws IOException { Map mapJars = new HashMap<>(); - // parent - if (parent instanceof ResourceClassLoader) { - Resource[] reses = ((ResourceClassLoader) parent).getResources(); - - if (reses != null) { - for (Resource r: reses) { - mapJars.put(r.getAbsolutePath(), r); - } - } - } Resource[] tmp; // maven @@ -525,9 +514,9 @@ else if (addionalResources instanceof List) { if (js != null) { return js; } - js = new JavaSettingsImpl(id, config, poms, osgis, paths.toArray(new Resource[paths.size()]), bundles.toArray(new Resource[bundles.size()]), loadCFMLClassPath, reloadOnChange, watchInterval, extensions.toArray(new String[extensions.size()])); + ((ConfigPro) config).setJavaSettings(id, js); return js; } diff --git a/core/src/main/java/lucee/transformer/bytecode/reflection/ASMProxyFactory.java b/core/src/main/java/lucee/transformer/bytecode/reflection/ASMProxyFactory.java index 25fa0904bb..b62daec2f0 100644 --- a/core/src/main/java/lucee/transformer/bytecode/reflection/ASMProxyFactory.java +++ b/core/src/main/java/lucee/transformer/bytecode/reflection/ASMProxyFactory.java @@ -143,7 +143,7 @@ public static ASMMethod getMethod(ExtendableClassLoader pcl, Resource classRoot, // try to load existing ASM Class Class asmClass; try { - asmClass = pcl.loadClass(className); + asmClass = ((ClassLoader) pcl).loadClass(className); // print.e("use existing class"); } catch (ClassNotFoundException cnfe) { @@ -170,7 +170,7 @@ private static ASMMethod getMethod(ExtendableClassLoader pcl, Resource classRoot // try to load existing ASM Class Class asmClass; try { - asmClass = pcl.loadClass(className); + asmClass = ((ClassLoader) pcl).loadClass(className); } catch (ClassNotFoundException cnfe) { byte[] barr = _createMethod(type, clazz, method, classRoot, className); diff --git a/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java b/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java index a0fcdbd6da..b80ef9b9aa 100644 --- a/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java +++ b/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java @@ -40,7 +40,6 @@ import lucee.commons.digest.HashUtil; import lucee.commons.io.IOUtil; import lucee.commons.io.res.Resource; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.PhysicalClassLoader; @@ -434,7 +433,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) throws IOException { + private static PhysicalClassLoader getRPCClassLoaderFromClasses(PageContext pc, Class extendz, Class... interfaces) { // extends and implement need to come from the same parent classloader PhysicalClassLoader pcl = null; if (extendz != null) { @@ -451,16 +450,13 @@ private static PhysicalClassLoader getRPCClassLoaderFromClasses(PageContext pc, return null; } - public static PhysicalClassLoader getRPCClassLoaderFromClass(PageContext pc, Class clazz) throws IOException { + public static PhysicalClassLoader getRPCClassLoaderFromClass(PageContext pc, Class clazz) { ClassLoader cl = clazz.getClassLoader(); pc = ThreadLocalPageContext.get(pc); if (cl != null) { if (cl instanceof PhysicalClassLoader) { return ((PhysicalClassLoader) cl); } - if (cl instanceof ResourceClassLoader && pc != null) { - return (PhysicalClassLoader) ((PageContextImpl) pc).getRPCClassLoader(false, (ResourceClassLoader) cl); - } } return null; } diff --git a/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java b/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java index c829725549..a381561e47 100644 --- a/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java +++ b/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java @@ -19,7 +19,7 @@ /** * Directory ClassLoader */ -public final class DynamicClassLoader extends ExtendableClassLoader { +public final class DynamicClassLoader extends ClassLoader implements ExtendableClassLoader { static { boolean res = registerAsParallelCapable();