From 4300d16bdd3d19eea9e54990ebe0046eee9e6f46 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 16 Aug 2024 18:58:08 +0200 Subject: [PATCH] LDEV-5040 - completely reorganise how javasettings are loaded --- .../commons/io/res/util/MavenClassLoader.java | 62 ++--- .../io/res/util/ResourceClassLoader.java | 106 +++----- .../java/lucee/commons/lang/ClassUtil.java | 11 +- .../commons/lang/PhysicalClassLoader.java | 29 --- .../java/lucee/runtime/PageContextImpl.java | 42 ++- .../lucee/runtime/config/ConfigAdmin.java | 2 +- .../java/lucee/runtime/config/ConfigImpl.java | 33 +-- .../java/lucee/runtime/config/ConfigPro.java | 2 +- .../runtime/config/ConfigWebFactory.java | 18 +- .../lucee/runtime/config/ConfigWebImpl.java | 3 +- .../lucee/runtime/config/ConfigWebUtil.java | 56 ---- .../config/SingleContextConfigWeb.java | 2 +- .../functions/decision/IsInstanceOf.java | 4 +- .../functions/other/CreateDynamicProxy.java | 4 +- .../runtime/functions/other/JavaProxy.java | 13 +- .../runtime/functions/string/JavaCast.java | 4 +- .../system/GetApplicationSettings.java | 3 +- .../runtime/listener/JavaSettingsImpl.java | 245 +++++++++++------- .../listener/ModernApplicationContext.java | 3 +- .../java/lucee/runtime/tag/Application.java | 2 +- .../bytecode/util/JavaProxyFactory.java | 58 ++--- loader/build.xml | 2 +- loader/pom.xml | 2 +- 23 files changed, 317 insertions(+), 389 deletions(-) diff --git a/core/src/main/java/lucee/commons/io/res/util/MavenClassLoader.java b/core/src/main/java/lucee/commons/io/res/util/MavenClassLoader.java index 0fbd5dfa79..9775c55cb6 100644 --- a/core/src/main/java/lucee/commons/io/res/util/MavenClassLoader.java +++ b/core/src/main/java/lucee/commons/io/res/util/MavenClassLoader.java @@ -1,43 +1,25 @@ package lucee.commons.io.res.util; -import java.io.IOException; -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import lucee.runtime.mvn.POM; - -public class MavenClassLoader extends ResourceClassLoader { - - private static Map instances = new ConcurrentHashMap<>(); - private POM pom; - - public MavenClassLoader(POM pom, ClassLoader parent) throws IOException { - super(pom.getJars(), parent); - this.pom = pom; - } - - public static MavenClassLoader getInstance(POM pom, ClassLoader parent) throws IOException { - MavenClassLoader mcl = instances.get(pom.hash()); - if (mcl == null) { - mcl = new MavenClassLoader(pom, parent); - instances.put(pom.hash(), mcl); - } - return mcl; - } - - public static MavenClassLoader getInstance(POM[] poms, ClassLoader parent) throws IOException { - if (poms == null || poms.length == 0) throw new IOException("you need to define at least one POM."); - - Arrays.sort(poms, (pom1, pom2) -> pom1.id().compareTo(pom2.id())); - - for (POM pom: poms) { - parent = getInstance(pom, parent); - } - return (MavenClassLoader) parent; - } - - public POM getPOM() { - return pom; - } +public class MavenClassLoader {// extends ResourceClassLoader { + /* + * private static Map instances = new ConcurrentHashMap<>(); private POM + * pom; + * + * public MavenClassLoader(POM pom, ClassLoader parent) throws IOException { super(pom.getJars(), + * parent); this.pom = pom; } + * + * public static MavenClassLoader getInstance(POM pom, ClassLoader parent) throws IOException { + * MavenClassLoader mcl = instances.get(pom.hash()); if (mcl == null) { mcl = new + * MavenClassLoader(pom, parent); instances.put(pom.hash(), mcl); } return mcl; } + * + * public static MavenClassLoader getInstance(POM[] poms, ClassLoader parent) throws IOException { + * if (poms == null || poms.length == 0) throw new + * IOException("you need to define at least one POM."); + * + * Arrays.sort(poms, (pom1, pom2) -> pom1.id().compareTo(pom2.id())); + * + * for (POM pom: poms) { parent = getInstance(pom, parent); } return (MavenClassLoader) parent; } + * + * public POM getPOM() { return pom; } + */ } 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 index b6eef31cd1..bfdc69ea74 100755 --- a/core/src/main/java/lucee/commons/io/res/util/ResourceClassLoader.java +++ b/core/src/main/java/lucee/commons/io/res/util/ResourceClassLoader.java @@ -20,11 +20,9 @@ import java.io.Closeable; import java.io.IOException; -import java.lang.ref.SoftReference; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -35,46 +33,63 @@ import lucee.commons.io.res.Resource; import lucee.commons.io.res.type.file.FileResource; import lucee.runtime.exp.PageException; -import lucee.runtime.type.util.ArrayUtil; /** * Classloader that load classes from resources */ public class ResourceClassLoader extends URLClassLoader implements Closeable { + private static Map classloaders = new ConcurrentHashMap<>(); - private final List resources = new ArrayList(); - private Map> customCLs; - private Integer hc = null; + private final Collection resources; + + private final String id; private static RC rc = new RC(); static { boolean res = registerAsParallelCapable(); } - /** - * Constructor of the class - * - * @param reses - * @param parent - * @throws PageException - */ - public ResourceClassLoader(Resource[] resources, ClassLoader parent) throws IOException { - super(doURLs(resources), parent); + public static ResourceClassLoader getInstance(Resource[] resources, ClassLoader parent) throws IOException { + List list = new ArrayList(); for (Resource r: resources) { - if (r != null) this.resources.add(r); + if (r != null) list.add(r); } - java.util.Collections.sort(this.resources, rc); + java.util.Collections.sort(list, rc); + return getInstance(list, parent); } - public ResourceClassLoader(Collection resources, ClassLoader parent) throws IOException { - super(doURLs(resources), parent); + public static ResourceClassLoader getInstance(Collection resources, ClassLoader parent) throws IOException { + List list = new ArrayList(); for (Resource r: resources) { - if (r != null) this.resources.add(r); + if (r != null) list.add(r); } - java.util.Collections.sort(this.resources, rc); + 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; } - public ResourceClassLoader(ClassLoader parent) { + private ResourceClassLoader(ClassLoader parent) { super(new URL[0], parent); + this.resources = new ArrayList(); + this.id = "orphan"; } /** @@ -113,7 +128,9 @@ public static URL[] doURLs(Resource[] reses) throws IOException { } private static URL doURL(Resource res) throws IOException { - if (!(res instanceof FileResource)) throw new IOException("resource [" + res.getPath() + "] must be a local file"); + if (!(res instanceof FileResource)) { + return ResourceUtil.toFile(res).toURL(); + } return ((FileResource) res).toURL(); } @@ -121,52 +138,13 @@ private static URL doURL(Resource res) throws IOException { public void close() { } - public ResourceClassLoader getCustomResourceClassLoader(Resource[] resources) throws IOException { - - if (ArrayUtil.isEmpty(resources)) return this; - Arrays.sort(resources); - String key = hash(resources); - SoftReference tmp = customCLs == null ? null : customCLs.get(key); - ResourceClassLoader rcl = tmp == null ? null : tmp.get(); - - if (rcl != null) return rcl; - - resources = ResourceUtil.merge(this.getResources(), resources); - rcl = new ResourceClassLoader(resources, getParent()); - - if (customCLs == null) customCLs = new ConcurrentHashMap>(); - - customCLs.put(key, new SoftReference(rcl)); - return rcl; - } - @Override public int hashCode() { - if (hc == null) { - synchronized (resources) { - if (hc == null) { - hc = _hashStr(getResources()).hashCode(); - } - } - } - return hc.intValue(); - } - - private String _hashStr(Resource[] resources) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < resources.length; i++) { - sb.append(ResourceUtil.getCanonicalPathEL(resources[i])); - sb.append(';'); - } - return sb.toString(); + return id.hashCode(); } public String hash() { - return hash(getResources()); - } - - private String hash(Resource[] resources) { - return HashUtil.create64BitHashAsString(_hashStr(resources)); + return id; } private static class RC implements Comparator { diff --git a/core/src/main/java/lucee/commons/lang/ClassUtil.java b/core/src/main/java/lucee/commons/lang/ClassUtil.java index 66c36fb597..13dcba83bc 100644 --- a/core/src/main/java/lucee/commons/lang/ClassUtil.java +++ b/core/src/main/java/lucee/commons/lang/ClassUtil.java @@ -53,6 +53,7 @@ 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; @@ -255,7 +256,7 @@ public static Class loadClass(PageContext pc, String className) throws ClassExce if (pc instanceof PageContextImpl) { ClassLoader cl; try { - cl = ((PageContextImpl) pc).getClassLoader(); + cl = ((PageContextImpl) pc).getClassLoader(null); } catch (IOException e) { ClassException ce = new ClassException("cannot load class through its string name"); @@ -1027,13 +1028,17 @@ public Class loadClass(String className, Class defaultValue, Set e } } - public static ClassLoader getClassLoader(Class clazz) { + public static ClassLoader getClassLoader(PageContext pc, Class clazz) throws IOException { ClassLoader cl = clazz.getClassLoader(); if (cl != null) return cl; + if (pc instanceof PageContextImpl) { + return ((PageContextImpl) pc).getClassLoader(); + } + // NEXT this is wrong Config config = ThreadLocalPageContext.getConfig(); if (config instanceof ConfigPro) { - return ((ConfigPro) config).getClassLoaderCore(); + return ((JavaSettingsImpl) ((ConfigPro) config).getJavaSettings()).getClassLoader(false); } return new lucee.commons.lang.ClassLoaderHelper().getClass().getClassLoader(); } diff --git a/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java b/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java index ba36232e0b..62a545fccf 100644 --- a/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java +++ b/core/src/main/java/lucee/commons/lang/PhysicalClassLoader.java @@ -25,23 +25,19 @@ import java.lang.ref.SoftReference; import java.net.URL; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import lucee.commons.digest.HashUtil; 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.util.ResourceUtil; import lucee.runtime.PageSourcePool; import lucee.runtime.config.Config; import lucee.runtime.config.ConfigPro; import lucee.runtime.exp.ApplicationException; -import lucee.runtime.type.util.ArrayUtil; import lucee.transformer.bytecode.util.ClassRenamer; /** @@ -267,31 +263,6 @@ public Resource getDirectory() { return directory; } - public PhysicalClassLoader getCustomClassLoader(Resource[] resources, boolean reload) throws IOException { - if (ArrayUtil.isEmpty(resources)) return this; - String key = hash(resources); - - if (reload && customCLs != null) customCLs.remove(key); - - SoftReference tmp = customCLs == null ? null : customCLs.get(key); - PhysicalClassLoader pcl = tmp == null ? null : tmp.get(); - if (pcl != null) return pcl; - pcl = new PhysicalClassLoader(config, getDirectory(), new ResourceClassLoader(resources, getParent()), true, pageSourcePool); - if (customCLs == null) customCLs = new ConcurrentHashMap>(); - customCLs.put(key, new SoftReference(pcl)); - return pcl; - } - - private String hash(Resource[] resources) { - Arrays.sort(resources); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < resources.length; i++) { - sb.append(ResourceUtil.getCanonicalPathEL(resources[i])); - sb.append(';'); - } - return HashUtil.create64BitHashAsString(sb.toString(), Character.MAX_RADIX); - } - public void clear() { clear(true); } diff --git a/core/src/main/java/lucee/runtime/PageContextImpl.java b/core/src/main/java/lucee/runtime/PageContextImpl.java index 37b395d7ea..b0a16e2746 100644 --- a/core/src/main/java/lucee/runtime/PageContextImpl.java +++ b/core/src/main/java/lucee/runtime/PageContextImpl.java @@ -66,11 +66,11 @@ 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; import lucee.commons.lang.HTMLEntities; -import lucee.commons.lang.PhysicalClassLoader; import lucee.commons.lang.StringUtil; import lucee.commons.lang.mimetype.MimeType; import lucee.commons.lang.types.RefBoolean; @@ -3846,39 +3846,29 @@ public JavaSettings getJavaSettings() { } public ClassLoader getClassLoader() throws IOException { - JavaSettingsImpl js = (JavaSettingsImpl) getJavaSettings(); - if (js != null) { - // TODO FUTURE 7 we do this to avoid any kind of regression, in Lucee 7 remove this - if (JAVA_SETTING_CLASSIC_MODE && !js.hasPoms() && !js.hasOSGis()) { - Resource[] jars = js.getResourcesTranslated(); - if (jars.length > 0) return config.getResourceClassLoader().getCustomResourceClassLoader(jars); - } - return js.getClassLoader(null, false); + return getClassLoader(null); + } + public ClassLoader getClassLoader(JavaSettings customJS) throws IOException { + JavaSettings js = getJavaSettings(); + if (customJS != null) { + js = JavaSettingsImpl.merge(config, js, customJS); } - return config.getResourceClassLoader(); + return ((JavaSettingsImpl) js).getClassLoader(false); } public ClassLoader getRPCClassLoader(boolean reload) throws IOException { - return getRPCClassLoader(reload, null); + return getRPCClassLoader(reload, (JavaSettings) null); } - public ClassLoader getRPCClassLoader(boolean reload, ClassLoader parent) throws IOException { - ClassLoader cl = ((ConfigPro) config).getRPCClassLoader(reload, parent); - JavaSettingsImpl js = (JavaSettingsImpl) getJavaSettings(); - if (js != null) { - // TODO FUTURE 7 we do this to avoid any kind of regression, in Lucee 7 remove this - if (JAVA_SETTING_CLASSIC_MODE && !js.hasPoms() && !js.hasOSGis()) { - Resource[] jars = js.getResourcesTranslated(); - if (jars.length > 0) return ((PhysicalClassLoader) cl).getCustomClassLoader(jars, reload); - } - else { - java.util.Collection jars = js.getAllResources(cl); - if (jars.size() > 0) return ((PhysicalClassLoader) cl).getCustomClassLoader(jars.toArray(new Resource[jars.size()]), reload); - } + 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 cl; } public void resetSession() { diff --git a/core/src/main/java/lucee/runtime/config/ConfigAdmin.java b/core/src/main/java/lucee/runtime/config/ConfigAdmin.java index 0b7ef33255..3c60f1a120 100755 --- a/core/src/main/java/lucee/runtime/config/ConfigAdmin.java +++ b/core/src/main/java/lucee/runtime/config/ConfigAdmin.java @@ -1189,7 +1189,7 @@ public static void updateJar(Config config, Resource resJar, boolean reloadWhenC if (fileLib.length() != resJar.length()) { IOUtil.closeEL(config.getClassLoader()); ResourceUtil.copy(resJar, fileLib); - if (reloadWhenClassicJar) ConfigWebUtil.reloadLib(config); + // NEXT if (reloadWhenClassicJar) ConfigWebUtil.reloadLib(config); } } diff --git a/core/src/main/java/lucee/runtime/config/ConfigImpl.java b/core/src/main/java/lucee/runtime/config/ConfigImpl.java index 8a15200142..4966343d38 100755 --- a/core/src/main/java/lucee/runtime/config/ConfigImpl.java +++ b/core/src/main/java/lucee/runtime/config/ConfigImpl.java @@ -390,6 +390,7 @@ public abstract class ConfigImpl extends ConfigBase implements ConfigPro { private ClassDefinition cdORMEngine; private ORMConfiguration ormConfig; private ResourceClassLoader resourceCL; + private JavaSettings js; private ImportDefintion componentDefaultImport = new ImportDefintionImpl(Constants.DEFAULT_PACKAGE, "*"); private boolean componentLocalSearch = true; @@ -701,10 +702,6 @@ public ResourceClassLoader getResourceClassLoader(ResourceClassLoader defaultVal return resourceCL; } - protected void setResourceClassLoader(ResourceClassLoader resourceCL) { - this.resourceCL = resourceCL; - } - @Override public Locale getLocale() { return locale; @@ -2267,8 +2264,8 @@ public ClassLoader getRPCClassLoader(boolean reload) throws IOException { } @Override - public ClassLoader getRPCClassLoader(boolean reload, ClassLoader parent) throws IOException { - String key = toKey(parent); + 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) { @@ -2277,18 +2274,16 @@ public ClassLoader getRPCClassLoader(boolean reload, ClassLoader parent) throws Resource dir = getClassDirectory().getRealResource("RPC/" + key); if (!dir.exists()) { ResourceUtil.createDirectoryEL(dir, true); - if (parent instanceof ResourceClassLoader) { - Resource file = dir.getRealResource("classloader-resources.json"); - Struct root = new StructImpl(); - root.setEL(KeyConstants._resources, ((ResourceClassLoader) 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); - } + 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); } } @@ -4033,7 +4028,7 @@ public JavaSettings getJavaSettings() { if (javaSettings == null) { synchronized (javaSettingsInstances) { if (javaSettings == null) { - javaSettings = JavaSettingsImpl.getInstance(this, new StructImpl()); + javaSettings = JavaSettingsImpl.getInstance(this, new StructImpl(), null); } } } diff --git a/core/src/main/java/lucee/runtime/config/ConfigPro.java b/core/src/main/java/lucee/runtime/config/ConfigPro.java index e8ba87bcc4..a5d9c44398 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigPro.java +++ b/core/src/main/java/lucee/runtime/config/ConfigPro.java @@ -190,7 +190,7 @@ public interface ConfigPro extends Config { public ResourceClassLoader getResourceClassLoader(); - public ClassLoader getRPCClassLoader(boolean reload, ClassLoader parent) throws IOException; + public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException; public PageSource toPageSource(Mapping[] mappings, Resource res, PageSource defaultValue); diff --git a/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java b/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java index 487d2a54d0..0651fd91be 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java +++ b/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java @@ -543,13 +543,12 @@ synchronized static void load(ConfigServerImpl cs, ConfigImpl config, ConfigWebI _loadSecurity(cs, config, root, log); if (LOG) LogUtil.logGlobal(ThreadLocalPageContext.getConfig(cs == null ? config : cs), Log.LEVEL_DEBUG, ConfigWebFactory.class.getName(), "loaded security"); } - try { - ConfigWebUtil.loadLib(cs, config); - } - catch (Throwable t) { - ExceptionUtil.rethrowIfNecessary(t); - log(config, log, t); + + if (!essentialOnly) { + _loadJavaSettings(cs, config, root, log); // define compile type + if (LOG) LogUtil.logGlobal(ThreadLocalPageContext.getConfig(cs == null ? config : cs), Log.LEVEL_DEBUG, ConfigWebFactory.class.getName(), "loaded java settings"); } + if (LOG) LogUtil.logGlobal(ThreadLocalPageContext.getConfig(cs == null ? config : cs), Log.LEVEL_DEBUG, ConfigWebFactory.class.getName(), "loaded lib"); if (!essentialOnly) { @@ -592,7 +591,6 @@ synchronized static void load(ConfigServerImpl cs, ConfigImpl config, ConfigWebI if (LOG) LogUtil.logGlobal(ThreadLocalPageContext.getConfig(cs == null ? config : cs), Log.LEVEL_DEBUG, ConfigWebFactory.class.getName(), "loaded application"); _loadJava(cs, config, root, log); // define compile type - if (!essentialOnly) _loadJavaSettings(cs, config, root, log); // define compile type if (LOG) LogUtil.logGlobal(ThreadLocalPageContext.getConfig(cs == null ? config : cs), Log.LEVEL_DEBUG, ConfigWebFactory.class.getName(), "loaded java"); if (!essentialOnly) { @@ -4294,11 +4292,15 @@ else if (hasCS) { private static void _loadJavaSettings(ConfigServerImpl configServer, ConfigImpl config, Struct root, Log log) { try { if (config instanceof ConfigServerImpl) { + + Resource lib = config.getLibraryDirectory(); + Resource[] libs = lib.listResources(ExtensionResourceFilter.EXTENSION_JAR_NO_DIR); + ConfigServerImpl csi = (ConfigServerImpl) config; Struct javasettings = ConfigWebUtil.getAsStruct(root, false, "javasettings"); if (javasettings != null && javasettings.size() > 0) { - JavaSettings js = JavaSettingsImpl.getInstance(config, javasettings); + JavaSettings js = JavaSettingsImpl.getInstance(config, javasettings, libs); csi.setJavaSettings(js); } } diff --git a/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java b/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java index a10d8fff20..eb2db80dc4 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java +++ b/core/src/main/java/lucee/runtime/config/ConfigWebImpl.java @@ -13,6 +13,7 @@ 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; @@ -779,7 +780,7 @@ public lucee.runtime.config.ConfigServer getConfigServer(java.lang.String arg0, } @Override - public java.lang.ClassLoader getRPCClassLoader(boolean arg0, java.lang.ClassLoader arg1) throws java.io.IOException { + public ClassLoader getRPCClassLoader(boolean arg0, ResourceClassLoader arg1) throws java.io.IOException { return instance.getRPCClassLoader(arg0, arg1); } diff --git a/core/src/main/java/lucee/runtime/config/ConfigWebUtil.java b/core/src/main/java/lucee/runtime/config/ConfigWebUtil.java index 6913419aff..d79322ed39 100755 --- a/core/src/main/java/lucee/runtime/config/ConfigWebUtil.java +++ b/core/src/main/java/lucee/runtime/config/ConfigWebUtil.java @@ -31,8 +31,6 @@ import javax.servlet.ServletConfig; import javax.servlet.ServletContext; -import org.osgi.framework.BundleContext; - import lucee.commons.digest.MD5; import lucee.commons.io.IOUtil; import lucee.commons.io.SystemUtil; @@ -40,12 +38,9 @@ import lucee.commons.io.log.LogUtil; import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourcesImpl; -import lucee.commons.io.res.filter.ExtensionResourceFilter; import lucee.commons.io.res.type.compress.CompressResource; import lucee.commons.io.res.type.compress.CompressResourceProvider; -import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; -import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.commons.net.URLDecoder; import lucee.loader.engine.CFMLEngine; @@ -70,9 +65,6 @@ import lucee.runtime.monitor.Monitor; import lucee.runtime.net.http.ReqRspUtil; import lucee.runtime.op.Caster; -import lucee.runtime.osgi.BundleBuilderFactory; -import lucee.runtime.osgi.BundleFile; -import lucee.runtime.osgi.OSGiUtil; import lucee.runtime.security.SecurityManager; import lucee.runtime.type.Array; import lucee.runtime.type.ArrayImpl; @@ -187,54 +179,6 @@ private static void _deploy(ConfigWeb cw, Resource src, Resource trg) throws IOE } } - public static void reloadLib(Config config) throws IOException { - if (config instanceof ConfigWeb) loadLib(((ConfigWebImpl) config).getConfigServerImpl(), (ConfigPro) config); - else loadLib(null, (ConfigPro) config); - } - - static void loadLib(ConfigServer configServer, ConfigPro config) throws IOException { - // get lib and classes resources - Resource lib = config.getLibraryDirectory(); - Resource[] libs = lib.listResources(ExtensionResourceFilter.EXTENSION_JAR_NO_DIR); - - // get resources from server config and merge - if (configServer != null) { - ResourceClassLoader rcl = ((ConfigPro) configServer).getResourceClassLoader(); - libs = ResourceUtil.merge(libs, rcl.getResources()); - } - - CFMLEngine engine = ConfigWebUtil.getCFMLEngine(config); - BundleContext bc = engine.getBundleContext(); - Log log = ThreadLocalPageContext.getLog(config, "application"); - BundleFile bf; - List list = new ArrayList(); - for (int i = 0; i < libs.length; i++) { - try { - bf = BundleFile.getInstance(libs[i], true); - // jar is not a bundle - if (bf == null) { - // convert to a bundle - BundleBuilderFactory factory = new BundleBuilderFactory(libs[i]); - factory.setVersion("0.0.0.0"); - Resource tmp = SystemUtil.getTempFile("jar", false); - factory.build(tmp); - IOUtil.copy(tmp, libs[i]); - bf = BundleFile.getInstance(libs[i], true); - } - - OSGiUtil.start(OSGiUtil.installBundle(bc, libs[i], true)); - - } - catch (Throwable t) { - ExceptionUtil.rethrowIfNecessary(t); - list.add(libs[i]); - log.log(Log.LEVEL_ERROR, "OSGi", t); - } - } - - ((ConfigImpl) config).setResourceClassLoader(new ResourceClassLoader(list.toArray(new Resource[list.size()]), SystemUtil.getCombinedClassLoader())); - } - /** * touch a file object by the string definition * diff --git a/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java b/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java index 75ff074c9e..7fc1a3c5d3 100644 --- a/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java +++ b/core/src/main/java/lucee/runtime/config/SingleContextConfigWeb.java @@ -733,7 +733,7 @@ public ClassLoader getRPCClassLoader(boolean reload) throws IOException { } @Override - public ClassLoader getRPCClassLoader(boolean reload, ClassLoader parent) throws IOException { + public ClassLoader getRPCClassLoader(boolean reload, ResourceClassLoader parent) throws IOException { return cs.getRPCClassLoader(reload, parent); } diff --git a/core/src/main/java/lucee/runtime/functions/decision/IsInstanceOf.java b/core/src/main/java/lucee/runtime/functions/decision/IsInstanceOf.java index 042c36af0c..2a848a9d59 100644 --- a/core/src/main/java/lucee/runtime/functions/decision/IsInstanceOf.java +++ b/core/src/main/java/lucee/runtime/functions/decision/IsInstanceOf.java @@ -38,7 +38,7 @@ public static boolean call(PageContext pc, Object obj, String typeName) throws P if (obj instanceof Component) return ((Component) obj).instanceOf(typeName); if (obj instanceof JavaObject) { try { - return Reflector.isInstaneOf(((PageContextImpl) pc).getClassLoader(), ((JavaObject) obj).getClazz(), typeName); + return Reflector.isInstaneOf(((PageContextImpl) pc).getClassLoader(null), ((JavaObject) obj).getClazz(), typeName); } catch (IOException ioe) { throw Caster.toPageException(ioe); @@ -47,7 +47,7 @@ public static boolean call(PageContext pc, Object obj, String typeName) throws P if (obj instanceof ObjectWrap) return call(pc, ((ObjectWrap) obj).getEmbededObject(), typeName); try { - return Reflector.isInstaneOf(((PageContextImpl) pc).getClassLoader(), obj.getClass(), typeName); + return Reflector.isInstaneOf(((PageContextImpl) pc).getClassLoader(null), obj.getClass(), typeName); } catch (IOException ioe) { throw Caster.toPageException(ioe); diff --git a/core/src/main/java/lucee/runtime/functions/other/CreateDynamicProxy.java b/core/src/main/java/lucee/runtime/functions/other/CreateDynamicProxy.java index 9abb2d91c2..08f6f33092 100644 --- a/core/src/main/java/lucee/runtime/functions/other/CreateDynamicProxy.java +++ b/core/src/main/java/lucee/runtime/functions/other/CreateDynamicProxy.java @@ -75,7 +75,7 @@ public static Object _call(PageContext pc, Object oCFC, Object oInterfaces) thro if (Decision.isArray(oInterfaces)) { Object[] arr = Caster.toNativeArray(oInterfaces); - ClassLoader cl = ((PageContextImpl) pc).getClassLoader(); + ClassLoader cl = ((PageContextImpl) pc).getClassLoader(null); interfaces = new Class[arr.length]; for (int i = 0; i < arr.length; i++) { if (arr[i] instanceof JavaObject) interfaces[i] = ((JavaObject) arr[i]).getClazz(); @@ -88,7 +88,7 @@ else if (oInterfaces instanceof JavaObject) { interfaces = new Class[] { ((JavaObject) oInterfaces).getClazz() }; } else if (oInterfaces instanceof Struct) { - ClassLoader cl = ((PageContextImpl) pc).getClassLoader(); + ClassLoader cl = ((PageContextImpl) pc).getClassLoader(null); interfaces = new Class[] { toClass(pc, cl, (Struct) oInterfaces) }; } else throw new FunctionException(pc, "CreateDynamicProxy", 2, "interfaces", "invalid type [" + Caster.toClassName(oInterfaces) + "] for class definition"); diff --git a/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java b/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java index a4f36fb3a9..a2b825fdbb 100644 --- a/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java +++ b/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java @@ -127,9 +127,9 @@ public static Class loadClass(PageContext pc, String className, Object pathOr return loadClassByPath(pc, className, arrPaths); } else if (Decision.isStruct(pathOrName)) { - JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(pathOrName)); + JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(pathOrName), null); try { - return ClassUtil.loadClass(js.getClassLoader(((PageContextImpl) pc).getClassLoader(), false), className); + return ClassUtil.loadClass(((PageContextImpl) pc).getClassLoader(js), className); } catch (IOException e) { throw Caster.toPageException(e); @@ -171,12 +171,11 @@ private static Class loadClassByPath(PageContext pc, String className, String // load class try { - - ClassLoader cl = pci.getClassLoader(); - if (!resources.isEmpty()) { - JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), resources); - cl = js.getClassLoader(cl, false); + JavaSettingsImpl js = null; + if (resources != null && !resources.isEmpty()) { + js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), null, resources); } + ClassLoader cl = pci.getClassLoader(js); Class clazz = null; try { diff --git a/core/src/main/java/lucee/runtime/functions/string/JavaCast.java b/core/src/main/java/lucee/runtime/functions/string/JavaCast.java index ff45012bbe..016bab3ec6 100644 --- a/core/src/main/java/lucee/runtime/functions/string/JavaCast.java +++ b/core/src/main/java/lucee/runtime/functions/string/JavaCast.java @@ -116,8 +116,8 @@ private static Class toClass(PageContext pc, String lcType, String type, Stru try { if (javaSettings != null) { - JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(javaSettings)); - return ClassUtil.loadClass(js.getClassLoader(((PageContextImpl) pc).getClassLoader(), false), type); + JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(javaSettings), null); + return ClassUtil.loadClass(((PageContextImpl) pc).getClassLoader(js), type); } return ClassUtil.loadClass(pc, type); } diff --git a/core/src/main/java/lucee/runtime/functions/system/GetApplicationSettings.java b/core/src/main/java/lucee/runtime/functions/system/GetApplicationSettings.java index 1b05a7902c..e70f561d62 100644 --- a/core/src/main/java/lucee/runtime/functions/system/GetApplicationSettings.java +++ b/core/src/main/java/lucee/runtime/functions/system/GetApplicationSettings.java @@ -19,7 +19,6 @@ package lucee.runtime.functions.system; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -419,7 +418,7 @@ public static Struct call(PageContext pc, boolean suppressFunctions, boolean onl // maven if (js instanceof JavaSettingsImpl) { JavaSettingsImpl jsi = (JavaSettingsImpl) js; - List poms = jsi.getPoms(); + java.util.Collection poms = jsi.getPoms(); if (poms != null) { Array arr = new ArrayImpl(); Struct s; diff --git a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java index 73aabeaca7..5ab350252c 100644 --- a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java +++ b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java @@ -20,16 +20,15 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; 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; @@ -57,8 +56,8 @@ public class JavaSettingsImpl implements JavaSettings { private static final int DEFAULT_WATCH_INTERVAL = 60; - private List poms; - private List osgis; + private Collection poms; + private Collection osgis; private final Resource[] resources; private Resource[] resourcesTranslated; private final Resource[] bundles; @@ -68,12 +67,17 @@ public class JavaSettingsImpl implements JavaSettings { private final int watchInterval; private final String[] watchedExtensions; private boolean hasBundlesTranslated; - private Map classLoaders = new ConcurrentHashMap(); + // private Map classLoaders = new ConcurrentHashMap(); + private ResourceClassLoader classLoader; private Config config; - public JavaSettingsImpl(Config config, List poms, List osgis, Resource[] resources, Resource[] bundles, Boolean loadCFMLClassPath, boolean reloadOnChange, - int watchInterval, String[] watchedExtensions) { + private String id; + + private JavaSettingsImpl(String id, Config config, Collection poms, Collection osgis, Resource[] resources, Resource[] bundles, Boolean loadCFMLClassPath, + boolean reloadOnChange, int watchInterval, String[] watchedExtensions) { this.config = config == null ? ThreadLocalPageContext.getConfig() : config; + this.id = id; this.poms = poms; this.osgis = osgis; this.resources = resources == null ? new Resource[0] : resources; @@ -86,11 +90,105 @@ public JavaSettingsImpl(Config config, List poms, List osgis, Resource[ // TODO needed? SystemExitScanner.validate(resources); } + public static JavaSettings merge(Config config, JavaSettings l, JavaSettings r) { + JavaSettingsImpl li = (JavaSettingsImpl) l; + JavaSettingsImpl ri = (JavaSettingsImpl) r; + + String id = HashUtil.create64BitHashAsString(li.id + ":" + ri.id); + + JavaSettings js = ((ConfigPro) config).getJavaSettings(id); + if (js != null) { + return js; + } + boolean lEmpty = true; + boolean rEmpty = true; + // poms + Map mapPOMs = new HashMap<>(); + if (ri.getPoms() != null) { + for (POM pom: ri.getPoms()) { + mapPOMs.put(pom.id(), pom); + rEmpty = false; + } + } + if (li.getPoms() != null) { + for (POM pom: li.getPoms()) { + mapPOMs.put(pom.id(), pom); + lEmpty = false; + } + } + + // osgis + Map mapOSGIs = new HashMap<>(); + if (ri.osgis != null) { + for (BD bd: ri.osgis) { + mapOSGIs.put(bd.toString(), bd); + rEmpty = false; + } + } + if (li.osgis != null) { + for (BD bd: li.osgis) { + mapOSGIs.put(bd.toString(), bd); + lEmpty = false; + } + } + + // resources + Map mapResources = new HashMap<>(); + for (Resource res: ri.getResources()) { + mapResources.put(res.getAbsolutePath(), res); + rEmpty = false; + } + for (Resource res: li.getResources()) { + mapResources.put(res.getAbsolutePath(), res); + lEmpty = false; + } + + // bundles + Map mapBundles = new HashMap<>(); + for (Resource res: ri.getBundles()) { + mapBundles.put(res.getAbsolutePath(), res); + rEmpty = false; + } + for (Resource res: li.getBundles()) { + mapBundles.put(res.getAbsolutePath(), res); + lEmpty = false; + } + + // watched extensions + Map mapWatched = new HashMap<>(); + if (ri.watchedExtensions != null) { + for (String str: ri.watchedExtensions) { + mapWatched.put(str, ""); + } + } + if (li.watchedExtensions != null) { + for (String str: li.watchedExtensions) { + mapWatched.put(str, ""); + } + } + + if (lEmpty) { + ((ConfigPro) config).setJavaSettings(id, r); + return r; + } + if (rEmpty) { + ((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()])); + + ((ConfigPro) config).setJavaSettings(id, js); + return js; + } + public boolean hasPoms() { return poms != null && poms.size() > 0; } - public List getPoms() { + public Collection getPoms() { return poms; } @@ -98,21 +196,12 @@ public boolean hasOSGis() { return osgis != null && osgis.size() > 0; } - public ClassLoader getClassLoader(ClassLoader parent, boolean reload) throws IOException { - if (parent == null) parent = ((ConfigPro) config).getResourceClassLoader(); - String key = hash(resources) + ":" + parent.getName(); - ResourceClassLoader classLoader = reload ? null : classLoaders.get(key); - - if (classLoader == null) { - Collection allResources = getAllResources(parent); - if (allResources.size() > 0) { - ResourceClassLoader modified = new ResourceClassLoader(allResources, parent); - classLoaders.put(key, modified); - return modified; - } - return parent; + 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; } @@ -161,17 +250,6 @@ public Collection getAllResources(ClassLoader parent) throws IOExcepti return mapJars.values(); } - private String hash(Resource[] resources) { - if (resources == null || resources.length == 0) return ""; - Arrays.sort(resources); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < resources.length; i++) { - sb.append(ResourceUtil.getCanonicalPathEL(resources[i])); - sb.append(';'); - } - return HashUtil.create64BitHashAsString(sb.toString()); - } - @Override public Resource[] getResources() { return resources; @@ -257,54 +335,15 @@ public String[] watchedExtensions() { return watchedExtensions; } - public static JavaSettings getInstance(Config config, List paths) { - - List names = new ArrayList<>(); - // load paths - if (paths != null) { - for (Resource p: paths) { - names.add("paths:" + p.getAbsolutePath()); - } - } - else paths = new ArrayList(); - - Boolean loadCFMLClassPath = null; - names.add("loadCFMLClassPath:" + loadCFMLClassPath); - - boolean reloadOnChange = false; - names.add("reloadOnChange:" + reloadOnChange); - - int watchInterval = DEFAULT_WATCH_INTERVAL; - names.add("watchInterval:" + watchInterval); - - // watchExtensions - List extensions = new ArrayList(); - - Collections.sort(names); - String id = HashUtil.create64BitHashAsString(names.toString()); - - JavaSettings js = ((ConfigPro) config).getJavaSettings(id); - if (js != null) { - return js; - } - - js = new JavaSettingsImpl(config, null, null, paths.toArray(new Resource[paths.size()]), new Resource[0], loadCFMLClassPath, reloadOnChange, watchInterval, - extensions.toArray(new String[extensions.size()])); - ((ConfigPro) config).setJavaSettings(id, js); - return js; - } - - public static JavaSettings getInstance(Config config, Struct sct) { - - // TODO faster hash? + public static JavaSettings getInstance(Config config, Struct data, Object addionalResources) { List names = new ArrayList<>(); // maven List poms = null; { - Object obj = sct.get(KeyConstants._maven, null); - if (obj == null) obj = sct.get(KeyConstants._mvn, null); + Object obj = data == null ? null : data.get(KeyConstants._maven, null); + if (obj == null) obj = data == null ? null : data.get(KeyConstants._mvn, null); if (obj != null) { Array arr = Caster.toArray(obj, null); if (arr == null) { @@ -344,7 +383,7 @@ public static JavaSettings getInstance(Config config, Struct sct) { // osgi List osgis = null; { - Object obj = sct.get(KeyConstants._osgi, null); + Object obj = data == null ? null : data.get(KeyConstants._osgi, null); if (obj != null) { Array arr = Caster.toArray(obj, null); if (arr == null) { @@ -358,7 +397,6 @@ public static JavaSettings getInstance(Config config, Struct sct) { if (arr != null) { Iterator it = arr.valueIterator(); String n, v; - Log log = config.getLog("application"); BD tmp; while (it.hasNext()) { Struct el = Caster.toStruct(it.next(), null); @@ -381,9 +419,9 @@ public static JavaSettings getInstance(Config config, Struct sct) { } // load paths - List paths; + Collection paths; { - Object obj = sct.get(KeyConstants._loadPaths, null); + Object obj = data == null ? null : data.get(KeyConstants._loadPaths, null); if (obj != null) { paths = loadPaths(ThreadLocalPageContext.get(), obj); for (Resource p: paths) { @@ -393,13 +431,34 @@ public static JavaSettings getInstance(Config config, Struct sct) { else paths = new ArrayList(); } + // addional resources + if (addionalResources != null) { + Map map = new HashMap<>(); + for (Resource r: paths) { + map.put(r.getAbsolutePath(), r); + } + if (addionalResources instanceof Resource[]) { + for (Resource r: (Resource[]) addionalResources) { + map.put(r.getAbsolutePath(), r); + names.add("addional:" + r.getAbsolutePath()); + } + } + else if (addionalResources instanceof List) { + for (Resource r: (List) addionalResources) { + map.put(r.getAbsolutePath(), r); + names.add("addional:" + r.getAbsolutePath()); + } + } + paths = map.values(); + } + // bundles paths List bundles; { - Object obj = sct.get(KeyConstants._bundlePaths, null); - if (obj == null) obj = sct.get(KeyConstants._bundles, null); - if (obj == null) obj = sct.get(KeyConstants._bundleDirectory, null); - if (obj == null) obj = sct.get(KeyConstants._bundleDirectories, null); + Object obj = data == null ? null : data.get(KeyConstants._bundlePaths, null); + if (obj == null) obj = data == null ? null : data.get(KeyConstants._bundles, null); + if (obj == null) obj = data == null ? null : data.get(KeyConstants._bundleDirectory, null); + if (obj == null) obj = data == null ? null : data.get(KeyConstants._bundleDirectories, null); if (obj != null) { bundles = loadPaths(ThreadLocalPageContext.get(), obj); for (Resource b: bundles) { @@ -410,9 +469,9 @@ public static JavaSettings getInstance(Config config, Struct sct) { } // loadCFMLClassPath - Boolean loadCFMLClassPath = Caster.toBoolean(sct.get(KeyConstants._loadCFMLClassPath, null), null); + Boolean loadCFMLClassPath = Caster.toBoolean(data == null ? null : data.get(KeyConstants._loadCFMLClassPath, null), null); if (loadCFMLClassPath == null) { - loadCFMLClassPath = Caster.toBoolean(sct.get(KeyConstants._loadColdFusionClassPath, null), null); + loadCFMLClassPath = Caster.toBoolean(data == null ? null : data.get(KeyConstants._loadColdFusionClassPath, null), null); } names.add("loadCFMLClassPath:" + loadCFMLClassPath); @@ -421,17 +480,17 @@ public static JavaSettings getInstance(Config config, Struct sct) { // reloadOnChange //// boolean reloadOnChange = Caster.toBooleanValue(sct.get(KeyConstants._reloadOnChange, null), // base.reloadOnChange()); - boolean reloadOnChange = Caster.toBooleanValue(sct.get(KeyConstants._reloadOnChange, null), false); + boolean reloadOnChange = Caster.toBooleanValue(data == null ? null : data.get(KeyConstants._reloadOnChange, null), false); names.add("reloadOnChange:" + reloadOnChange); // watchInterval //// int watchInterval = Caster.toIntValue(sct.get(KeyConstants._watchInterval, null), // base.watchInterval()); - int watchInterval = Caster.toIntValue(sct.get(KeyConstants._watchInterval, null), DEFAULT_WATCH_INTERVAL); + int watchInterval = Caster.toIntValue(data == null ? null : data.get(KeyConstants._watchInterval, null), DEFAULT_WATCH_INTERVAL); names.add("watchInterval:" + watchInterval); // watchExtensions - Object obj = sct.get(KeyConstants._watchExtensions, null); + Object obj = data == null ? null : data.get(KeyConstants._watchExtensions, null); List extensions = new ArrayList(); if (obj != null) { Array arr; @@ -467,8 +526,8 @@ public static JavaSettings getInstance(Config config, Struct sct) { return js; } - js = new JavaSettingsImpl(config, poms, osgis, paths.toArray(new Resource[paths.size()]), bundles.toArray(new Resource[bundles.size()]), loadCFMLClassPath, reloadOnChange, - watchInterval, extensions.toArray(new String[extensions.size()])); + 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; } @@ -525,5 +584,11 @@ public BD(String name, String version) { this.version = version; } + @Override + public String toString() { + return name + ":" + version; + } + } + } \ No newline at end of file diff --git a/core/src/main/java/lucee/runtime/listener/ModernApplicationContext.java b/core/src/main/java/lucee/runtime/listener/ModernApplicationContext.java index 90327feffd..4ced983fb7 100644 --- a/core/src/main/java/lucee/runtime/listener/ModernApplicationContext.java +++ b/core/src/main/java/lucee/runtime/listener/ModernApplicationContext.java @@ -1815,7 +1815,8 @@ private JavaSettings initJava() { Object o = get(component, JAVA_SETTING, null); if (o != null && Decision.isStruct(o)) { - javaSettings = JavaSettingsImpl.getInstance(config, Caster.toStruct(o, null)); + javaSettings = JavaSettingsImpl.getInstance(config, Caster.toStruct(o, null), null); + javaSettings = JavaSettingsImpl.merge(config, javaSettings, getDefaultJavaSettings(config)); } if (javaSettings == null) { javaSettings = getDefaultJavaSettings(config); diff --git a/core/src/main/java/lucee/runtime/tag/Application.java b/core/src/main/java/lucee/runtime/tag/Application.java index 3a57ef0748..4355686d01 100644 --- a/core/src/main/java/lucee/runtime/tag/Application.java +++ b/core/src/main/java/lucee/runtime/tag/Application.java @@ -981,7 +981,7 @@ else if ((sct = Caster.toStruct(e.getValue(), null)) != null) { if (ac instanceof ApplicationContextSupport) { ApplicationContextSupport appContextSup = ((ApplicationContextSupport) ac); - if (javaSettings != null) appContextSup.setJavaSettings(JavaSettingsImpl.getInstance(pageContext.getConfig(), javaSettings)); + if (javaSettings != null) appContextSup.setJavaSettings(JavaSettingsImpl.getInstance(pageContext.getConfig(), javaSettings, null)); if (xmlFeatures != null) appContextSup.setXmlFeatures(xmlFeatures); if (searchQueries != null) appContextSup.setAllowImplicidQueryCall(searchQueries.booleanValue()); if (regex != null) appContextSup.setRegex(regex); 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 5ff15b9903..a0fcdbd6da 100644 --- a/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java +++ b/core/src/main/java/lucee/transformer/bytecode/util/JavaProxyFactory.java @@ -39,10 +39,9 @@ import lucee.commons.digest.HashUtil; 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.commons.io.res.util.ResourceUtil; -import lucee.commons.lang.ClassUtil; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.PhysicalClassLoader; import lucee.commons.lang.StringUtil; @@ -53,6 +52,7 @@ 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; @@ -140,22 +140,14 @@ public static Object createProxy(Object defaultValue, PageContext pc, UDF udf, C public static Object createProxy(PageContext pc, UDF udf, Class interf) throws PageException, IOException { PageContextImpl pci = (PageContextImpl) pc; - ClassLoader parent = ClassUtil.getClassLoader(interf); + PhysicalClassLoader pcl = getRPCClassLoaderFromClass(pc, interf); + if (pcl == null) pcl = (PhysicalClassLoader) pci.getRPCClassLoader(false); if (!interf.isInterface()) throw new IOException("definition [" + interf.getName() + "] is a class and not a interface"); Type typeExtends = Types.OBJECT; Type typeInterface = Type.getType(interf); String strInterface = typeInterface.getInternalName(); - - // get ClassLoader - PhysicalClassLoader pcl = null; - try { - pcl = (PhysicalClassLoader) pci.getRPCClassLoader(false, parent); - } - catch (IOException e) { - throw Caster.toPageException(e); - } String className = createClassName("udf", null, pcl.getDirectory(), Object.class, interf); Resource classFile = pcl.getDirectory().getRealResource(className.concat(".class")); @@ -219,7 +211,6 @@ public static Object createProxy(PageContext pc, UDF udf, Class interf) throws P ResourceUtil.touch(classFile); IOUtil.copy(new ByteArrayInputStream(barr), classFile, true); - pcl = (PhysicalClassLoader) pci.getRPCClassLoader(true, parent); Class clazz = pcl.loadClass(className, barr); return newInstance(clazz, pc.getConfig(), udf); } @@ -240,7 +231,8 @@ 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; - ClassLoader parent = extractClassLoaders(extendz, interfaces); + PhysicalClassLoader pcl = getRPCClassLoaderFromClasses(pc, extendz, interfaces); + if (pcl == null) pcl = (PhysicalClassLoader) pci.getRPCClassLoader(false); if (extendz == null) extendz = Object.class; if (interfaces == null) interfaces = new Class[0]; @@ -257,15 +249,6 @@ public static Object createProxy(PageContext pc, final Component cfc, Class exte strInterfaces[i] = typeInterfaces[i].getInternalName(); } - // get ClassLoader - PhysicalClassLoader pcl = null; - try { - pcl = (PhysicalClassLoader) pci.getRPCClassLoader(false, parent); - } - catch (IOException e) { - throw Caster.toPageException(e); - } - String className = createClassName("cfc", cfc, pcl.getDirectory(), extendz, interfaces); String classPath = className.replace('.', '/'); // Ensure classPath is using slashes Resource classFile = pcl.getDirectory().getRealResource(classPath.concat(".class")); @@ -399,7 +382,6 @@ public static Object createProxy(PageContext pc, final Component cfc, Class exte ResourceUtil.touch(classFile); IOUtil.copy(new ByteArrayInputStream(barr), classFile, true); - pcl = (PhysicalClassLoader) pci.getRPCClassLoader(true, parent); Class clazz = pcl.loadClass(className, barr); return newInstance(clazz, pc.getConfig(), cfc); } @@ -452,21 +434,35 @@ public static Object createProxy(PageContext pc, final Component cfc, Class exte * // adapter.returnValue(); adapter.endMethod(); } */ - private static ClassLoader extractClassLoaders(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 - ClassLoader cl = null; + PhysicalClassLoader pcl = null; if (extendz != null) { - cl = ClassUtil.getClassLoader(extendz); - if (cl != null) return cl; + pcl = getRPCClassLoaderFromClass(pc, extendz); + if (pcl != null) return pcl; } if (interfaces != null) { for (Class cls: interfaces) { - cl = ClassUtil.getClassLoader(cls); - if (cl != null) return cl; + pcl = getRPCClassLoaderFromClass(pc, cls); + if (pcl != null) return pcl; + } + } + return null; + } + + 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); + } + if (cl instanceof ResourceClassLoader && pc != null) { + return (PhysicalClassLoader) ((PageContextImpl) pc).getRPCClassLoader(false, (ResourceClassLoader) cl); } } - return SystemUtil.getCombinedClassLoader(); + return null; } private static void _createProxy(ClassWriter cw, Set cDone, Map mDone, UDF udf, Class clazz, String className) throws IOException { diff --git a/loader/build.xml b/loader/build.xml index b279be5d8b..f3607fdfc8 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index baae0752e8..af485fb2fe 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.46-SNAPSHOT + 6.2.0.47-SNAPSHOT jar Lucee Loader Build