From 58eef07d34a108e71630d49e4eecc13224d2f4b9 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Mon, 22 Jul 2024 10:04:44 +0200 Subject: [PATCH] LDEV-5033 - add argument "javacast" --- .../java/lucee/runtime/PageContextImpl.java | 18 +-- .../runtime/functions/other/JavaProxy.java | 12 +- .../runtime/functions/string/JavaCast.java | 20 +-- .../runtime/listener/JavaSettingsImpl.java | 145 +++++++++++------- loader/build.xml | 2 +- loader/pom.xml | 2 +- 6 files changed, 115 insertions(+), 84 deletions(-) diff --git a/core/src/main/java/lucee/runtime/PageContextImpl.java b/core/src/main/java/lucee/runtime/PageContextImpl.java index 312a5c7beb..7ef29a0ddb 100644 --- a/core/src/main/java/lucee/runtime/PageContextImpl.java +++ b/core/src/main/java/lucee/runtime/PageContextImpl.java @@ -228,7 +228,7 @@ public final class PageContextImpl extends PageContext { private static final RefBoolean DUMMY_BOOL = new RefBooleanImpl(false); - private static final boolean JAVA_SETTING_CLASSIC_MODE = true; + private static final boolean JAVA_SETTING_CLASSIC_MODE = false; private static int counter = 0; /** @@ -3835,23 +3835,23 @@ public ORMSession getORMSession(boolean create) throws PageException { return ormSession; } - public ClassLoader getClassLoader() throws IOException { - return getClassLoader(null); - } + /* + * public ClassLoader getClassLoader() throws IOException { return getClassLoader(null); } + */ public JavaSettings getJavaSettings() { return getApplicationContext().getJavaSettings(); } - public ClassLoader getClassLoader(Resource[] reses) throws IOException { + 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()) { + if (JAVA_SETTING_CLASSIC_MODE && !js.hasPoms() && !js.hasOSGis()) { Resource[] jars = js.getResourcesTranslated(); if (jars.length > 0) return config.getResourceClassLoader().getCustomResourceClassLoader(jars); } - return js.getResourceClassLoader(reses); + return js.getClassLoader(null, false); } return config.getResourceClassLoader(); @@ -3866,12 +3866,12 @@ public ClassLoader getRPCClassLoader(boolean reload, ClassLoader[] parents) thro 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()) { + 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(null); + java.util.Collection jars = js.getAllResources(cl); if (jars.size() > 0) return ((PhysicalClassLoader) cl).getCustomClassLoader(jars.toArray(new Resource[jars.size()]), reload); } 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 2e94c06c10..a4f36fb3a9 100644 --- a/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java +++ b/core/src/main/java/lucee/runtime/functions/other/JavaProxy.java @@ -21,6 +21,7 @@ */ package lucee.runtime.functions.other; +import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; @@ -128,12 +129,11 @@ public static Class loadClass(PageContext pc, String className, Object pathOr else if (Decision.isStruct(pathOrName)) { JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(pathOrName)); try { - return js.getResourceClassLoader(null).loadClass(className); + return ClassUtil.loadClass(js.getClassLoader(((PageContextImpl) pc).getClassLoader(), false), className); } - catch (Exception e) { + catch (IOException e) { throw Caster.toPageException(e); } - } return loadClassByPath(pc, className, ListUtil.toStringArray(Caster.toArray(pathOrName))); @@ -172,7 +172,11 @@ private static Class loadClassByPath(PageContext pc, String className, String // load class try { - ClassLoader cl = resources.isEmpty() ? pci.getClassLoader() : pci.getClassLoader(resources.toArray(new Resource[resources.size()])); + ClassLoader cl = pci.getClassLoader(); + if (!resources.isEmpty()) { + JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), resources); + cl = js.getClassLoader(cl, false); + } 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 732901cb32..ff45012bbe 100644 --- a/core/src/main/java/lucee/runtime/functions/string/JavaCast.java +++ b/core/src/main/java/lucee/runtime/functions/string/JavaCast.java @@ -21,13 +21,14 @@ */ package lucee.runtime.functions.string; +import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -import lucee.commons.lang.ClassException; import lucee.commons.lang.ClassUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.PageContext; +import lucee.runtime.PageContextImpl; import lucee.runtime.exp.ExpressionException; import lucee.runtime.exp.PageException; import lucee.runtime.ext.function.Function; @@ -112,20 +113,15 @@ private static Class toClass(PageContext pc, String lcType, String type, Stru if (lcType.equals("bigdecimal")) { return BigDecimal.class; } - if (javaSettings != null) { - JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(javaSettings)); - try { - return js.getResourceClassLoader(null).loadClass(type); - } - catch (Exception e) { - throw Caster.toPageException(e); - } - } - try { + try { + if (javaSettings != null) { + JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(javaSettings)); + return ClassUtil.loadClass(js.getClassLoader(((PageContextImpl) pc).getClassLoader(), false), type); + } return ClassUtil.loadClass(pc, type); } - catch (ClassException e) { + catch (IOException e) { throw Caster.toPageException(e); } } diff --git a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java index 08852b0dd6..73aabeaca7 100644 --- a/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java +++ b/core/src/main/java/lucee/runtime/listener/JavaSettingsImpl.java @@ -22,6 +22,7 @@ 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; @@ -32,7 +33,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.MavenClassLoader; import lucee.commons.io.res.util.ResourceClassLoader; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.StringUtil; @@ -98,22 +98,13 @@ public boolean hasOSGis() { return osgis != null && osgis.size() > 0; } - public ClassLoader getRPCClassLoader(ClassLoader parent, boolean reload) throws IOException { - return getClassLoader(parent, null, false); - - } - - public ResourceClassLoader getResourceClassLoader(Resource[] resources) throws IOException { - ResourceClassLoader parent = ((ConfigPro) config).getResourceClassLoader(); - return (ResourceClassLoader) getClassLoader(parent, resources, false); - } - - private ClassLoader getClassLoader(ClassLoader parent, Resource[] resources, boolean reload) throws IOException { + 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(resources); + Collection allResources = getAllResources(parent); if (allResources.size() > 0) { ResourceClassLoader modified = new ResourceClassLoader(allResources, parent); classLoaders.put(key, modified); @@ -125,8 +116,19 @@ private ClassLoader getClassLoader(ClassLoader parent, Resource[] resources, boo return classLoader; } - public Collection getAllResources(Resource[] resources) throws IOException { + 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 @@ -152,45 +154,13 @@ public Collection getAllResources(Resource[] resources) throws IOExcep } // resources passed in - if (resources != null && resources.length > 0) { - for (Resource r: resources) { - mapJars.put(r.getAbsolutePath(), r); - } - } + /* + * if (resources != null && resources.length > 0) { for (Resource r: resources) { + * mapJars.put(r.getAbsolutePath(), r); } } + */ return mapJars.values(); } - private ClassLoader getClassLoaderOld(ClassLoader parent, Resource[] resources, boolean reload) throws IOException { - String key = hash(resources) + ":" + parent.getName(); - ResourceClassLoader classLoader = reload ? null : classLoaders.get(key); - ResourceClassLoader modified = null; - if (classLoader == null) { - // maven - if (poms != null) { - for (POM pom: poms) { - parent = modified = new MavenClassLoader(pom, parent); - } - } - - // TODO OSGi - - // jars - Resource[] jars = getResourcesTranslated(); - if (jars.length > 0) { - parent = modified = new ResourceClassLoader(jars, parent); - } - - if (resources != null && resources.length > 0) { - parent = modified = new ResourceClassLoader(resources, parent); - } - - if (modified != null) classLoaders.put(key, modified); - return parent; - } - - return classLoader; - } - private String hash(Resource[] resources) { if (resources == null || resources.length == 0) return ""; Arrays.sort(resources); @@ -287,16 +257,49 @@ public String[] watchedExtensions() { return watchedExtensions; } - public static JavaSettings getInstance(Config config, Struct sct) { + public static JavaSettings getInstance(Config config, List paths) { - // TODO faster hash? - String id = HashUtil.create64BitHashAsString(sct.toString()); + 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? + + List names = new ArrayList<>(); + // maven List poms = null; { @@ -328,7 +331,9 @@ public static JavaSettings getInstance(Config config, Struct sct) { s = Caster.toString(el.get(KeyConstants._scope, null), null); if (!StringUtil.isEmpty(g) && !StringUtil.isEmpty(a)) { if (poms == null) poms = new ArrayList<>(); - poms.add(POM.getInstance(dir, g, a, v, MavenUtil.toScopes(s, POM.SCOPE_COMPILE), log)); + POM tmp = POM.getInstance(dir, g, a, v, MavenUtil.toScopes(s, POM.SCOPE_COMPILE), log); + poms.add(tmp); + names.add("maven:" + tmp.getGroupId() + ":" + tmp.getArtifactId() + ":" + tmp.getVersion()); } } } @@ -354,6 +359,7 @@ public static JavaSettings getInstance(Config config, Struct sct) { Iterator it = arr.valueIterator(); String n, v; Log log = config.getLog("application"); + BD tmp; while (it.hasNext()) { Struct el = Caster.toStruct(it.next(), null); if (el != null) { @@ -364,7 +370,9 @@ public static JavaSettings getInstance(Config config, Struct sct) { if (!StringUtil.isEmpty(n, true)) { if (osgis == null) osgis = new ArrayList<>(); - osgis.add(new BD(n.trim(), v == null ? v : v.trim())); + tmp = new BD(n.trim(), v == null ? v : v.trim()); + osgis.add(tmp); + names.add("osgi:" + tmp.name + ":" + tmp.version); } } } @@ -378,6 +386,9 @@ public static JavaSettings getInstance(Config config, Struct sct) { Object obj = sct.get(KeyConstants._loadPaths, null); if (obj != null) { paths = loadPaths(ThreadLocalPageContext.get(), obj); + for (Resource p: paths) { + names.add("paths:" + p.getAbsolutePath()); + } } else paths = new ArrayList(); } @@ -391,23 +402,33 @@ public static JavaSettings getInstance(Config config, Struct sct) { if (obj == null) obj = sct.get(KeyConstants._bundleDirectories, null); if (obj != null) { bundles = loadPaths(ThreadLocalPageContext.get(), obj); + for (Resource b: bundles) { + names.add("bundles:" + b.getAbsolutePath()); + } } else bundles = new ArrayList(); } + // loadCFMLClassPath Boolean loadCFMLClassPath = Caster.toBoolean(sct.get(KeyConstants._loadCFMLClassPath, null), null); - if (loadCFMLClassPath == null) loadCFMLClassPath = Caster.toBoolean(sct.get(KeyConstants._loadColdFusionClassPath, null), null); + if (loadCFMLClassPath == null) { + loadCFMLClassPath = Caster.toBoolean(sct.get(KeyConstants._loadColdFusionClassPath, null), null); + + } + names.add("loadCFMLClassPath:" + loadCFMLClassPath); //// if (loadCFMLClassPath == null) loadCFMLClassPath = base.loadCFMLClassPath(); // reloadOnChange //// boolean reloadOnChange = Caster.toBooleanValue(sct.get(KeyConstants._reloadOnChange, null), // base.reloadOnChange()); boolean reloadOnChange = Caster.toBooleanValue(sct.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); + names.add("watchInterval:" + watchInterval); // watchExtensions Object obj = sct.get(KeyConstants._watchExtensions, null); @@ -433,9 +454,19 @@ public static JavaSettings getInstance(Config config, Struct sct) { ext = ext.trim(); if (ext.startsWith(".")) ext = ext.substring(1); if (ext.startsWith("*.")) ext = ext.substring(2); + names.add("ext:" + ext); extensions.add(ext); } } + + Collections.sort(names); + String id = HashUtil.create64BitHashAsString(names.toString()); + + JavaSettings js = ((ConfigPro) config).getJavaSettings(id); + if (js != null) { + 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()])); ((ConfigPro) config).setJavaSettings(id, js); @@ -462,7 +493,7 @@ private static java.util.List loadPaths(PageContext pc, Object obj) { if (path == null) continue; res = AppListenerUtil.toResourceExisting(pc.getConfig(), pc.getApplicationContext(), path, false); if (res == null || !res.exists()) res = ResourceUtil.toResourceExisting(pc, path, true, null); - if (res != null) list.add(res); + if (res != null) list.add(ResourceUtil.getCanonicalResourceEL(res)); } catch (Exception e) { LogUtil.log(pc, ModernApplicationContext.class.getName(), e); diff --git a/loader/build.xml b/loader/build.xml index 63f0671158..739e530c48 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 6eb4debca1..dbf925211a 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.26-SNAPSHOT + 6.2.0.27-SNAPSHOT jar Lucee Loader Build