From b14db8e75b95d45ff180bfc14d390d0849eef891 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 13:55:00 +0100 Subject: [PATCH 01/46] LDEV-5043 - allow alias "updateSiteURL" --- core/src/main/java/lucee/runtime/config/ConfigWebFactory.java | 1 + loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java b/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java index 734124a24d..7837bef855 100644 --- a/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java +++ b/core/src/main/java/lucee/runtime/config/ConfigWebFactory.java @@ -3558,6 +3558,7 @@ private static void _loadUpdate(ConfigServer configServer, Config config, Struct cs.setUpdateType(getAttr(root, "updateType")); String location = getAttr(root, "updateLocation"); + if (StringUtil.isEmpty(location, true)) location = getAttr(root, "updateSiteURL"); if (!StringUtil.isEmpty(location, true)) { location = location.trim(); if ("http://update.lucee.org".equals(location)) location = DEFAULT_LOCATION; diff --git a/loader/build.xml b/loader/build.xml index 197e25f2b4..9b874ae03c 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index b81a04188e..1e7c3ae5d4 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.1.2.10-SNAPSHOT + 6.1.2.11-SNAPSHOT jar Lucee Loader Build From 5e398a90e8a6860840e8f45f5cfb884db7dc0853 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 13 Dec 2024 15:03:07 +0100 Subject: [PATCH 02/46] LDEV-5198 test case for bitOr regression https://luceeserver.atlassian.net/browse/LDEV-5198 --- test/tickets/LDEV5198.cfc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 test/tickets/LDEV5198.cfc diff --git a/test/tickets/LDEV5198.cfc b/test/tickets/LDEV5198.cfc new file mode 100644 index 0000000000..d3f7d7b06e --- /dev/null +++ b/test/tickets/LDEV5198.cfc @@ -0,0 +1,32 @@ +component extends = "org.lucee.cfml.test.LuceeTestCase" skip=true { + + function beforeAll(){ + variables.preciseMath = getApplicationSettings().preciseMath; + }; + + function afterAll(){ + application action="update" preciseMath=variables.preciseMath; + }; + + function run( testResults, testBox ){ + describe( "LDEV-5198 regression", function(){ + + it( "bit preciseMath=false", function(){ + application action="update" preciseMath=false; + var t= 138; + var num = 9103313; + expect ( bitSHLN( t, 24) ).toBe( 3305111552 ); + expect ( bitOr( num, 3305111552) ).toBe( 3314214865 ); // returns 3314214912 + }); + + it( "bit preciseMath=true", function(){ + application action="update" preciseMath=true; + var t= 138; + var num = 9103313; + expect ( bitSHLN( t, 24) ).toBe( 3305111552 ); + expect ( bitOr( num, 3305111552) ).toBe( 3314214865 ); // returns 3314214912 + }); + } ); + } + +} From f8a2b7d4c9b31792b71812b6cd780b65983f9977 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 13 Dec 2024 15:16:32 +0100 Subject: [PATCH 03/46] LDEV-5198 fix test --- test/tickets/LDEV5198.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tickets/LDEV5198.cfc b/test/tickets/LDEV5198.cfc index d3f7d7b06e..f9ac57d2fe 100644 --- a/test/tickets/LDEV5198.cfc +++ b/test/tickets/LDEV5198.cfc @@ -13,7 +13,7 @@ component extends = "org.lucee.cfml.test.LuceeTestCase" skip=true { it( "bit preciseMath=false", function(){ application action="update" preciseMath=false; - var t= 138; + var t= 197; var num = 9103313; expect ( bitSHLN( t, 24) ).toBe( 3305111552 ); expect ( bitOr( num, 3305111552) ).toBe( 3314214865 ); // returns 3314214912 @@ -21,7 +21,7 @@ component extends = "org.lucee.cfml.test.LuceeTestCase" skip=true { it( "bit preciseMath=true", function(){ application action="update" preciseMath=true; - var t= 138; + var t= 197; var num = 9103313; expect ( bitSHLN( t, 24) ).toBe( 3305111552 ); expect ( bitOr( num, 3305111552) ).toBe( 3314214865 ); // returns 3314214912 From 341753183ddb040d3c3a610482b317e7dbebdbfe Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 15:53:11 +0100 Subject: [PATCH 04/46] DC-5198 - overload toDoubleValue with long argument --- core/src/main/java/lucee/runtime/op/Caster.java | 8 ++++++++ loader/build.xml | 2 +- loader/pom.xml | 2 +- test/tickets/LDEV5198.cfc | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/runtime/op/Caster.java b/core/src/main/java/lucee/runtime/op/Caster.java index 2e10c42f4e..510c3a48db 100755 --- a/core/src/main/java/lucee/runtime/op/Caster.java +++ b/core/src/main/java/lucee/runtime/op/Caster.java @@ -751,6 +751,14 @@ public static double toDoubleValue(Number n) { return n.doubleValue(); } + public static double toDoubleValue(long l) { + return l; + } + + public static double toDoubleValue(Long l) { + return l.doubleValue(); + } + public static double toDoubleValue(float f) { return f; } diff --git a/loader/build.xml b/loader/build.xml index 29f520e948..5527c4ef94 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 0a0d262558..858c24edbc 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.212-SNAPSHOT + 6.2.0.213-SNAPSHOT jar Lucee Loader Build diff --git a/test/tickets/LDEV5198.cfc b/test/tickets/LDEV5198.cfc index f9ac57d2fe..dd44b3183b 100644 --- a/test/tickets/LDEV5198.cfc +++ b/test/tickets/LDEV5198.cfc @@ -1,4 +1,4 @@ -component extends = "org.lucee.cfml.test.LuceeTestCase" skip=true { +component extends = "org.lucee.cfml.test.LuceeTestCase" { function beforeAll(){ variables.preciseMath = getApplicationSettings().preciseMath; From 67d50d114d5fec20692f9fc46db7498ad4c4d87b Mon Sep 17 00:00:00 2001 From: Saravanamuthu Aka CF Mitrah Date: Fri, 13 Dec 2024 20:23:34 +0530 Subject: [PATCH 05/46] LDEV-5173 test cases for add support for epoch and epochms for ParseDateTime (#2454) --- test/tickets/LDEV5173.cfc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/tickets/LDEV5173.cfc diff --git a/test/tickets/LDEV5173.cfc b/test/tickets/LDEV5173.cfc new file mode 100644 index 0000000000..8c8193e262 --- /dev/null +++ b/test/tickets/LDEV5173.cfc @@ -0,0 +1,21 @@ +component extends = "org.lucee.cfml.test.LuceeTestCase" skip="true" { + function run( testResults, testBox ){ + describe( "Test for LDEV-5173", function() { + beforeEach( function(){ + variables.startingTZ=getTimeZone(); + setTimeZone("IST"); + }); + afterEach( function(){ + setTimeZone(variables.startingTZ?:"UTC"); + }); + it( title="parseDateTime with format 'epoch'", body=function( currentSpec ) { + date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epoch" ); + expect(toString(parseDateTime(date=date, format="epoch"))).toBe("{ts '2024-12-11 16:19:54'}"); + }); + it( title="parseDateTime with format 'epochms'", body=function( currentSpec ) { + date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epochms" ); + expect(toString(parseDateTime(date=date, format="epochms"))).toBe("{ts '2024-12-11 16:19:54'}"); + }); + } ); + } +} From 128f35b4b212cc2b8d0ca6fe4cb0026c59653a81 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 16:11:29 +0100 Subject: [PATCH 06/46] DC-5198 - overload toDouble with long argument --- core/src/main/java/lucee/runtime/op/Caster.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/runtime/op/Caster.java b/core/src/main/java/lucee/runtime/op/Caster.java index 510c3a48db..9328c46ff1 100755 --- a/core/src/main/java/lucee/runtime/op/Caster.java +++ b/core/src/main/java/lucee/runtime/op/Caster.java @@ -317,12 +317,20 @@ public static Boolean toBoolean(String str, Boolean defaultValue) { * @throws PageException */ public static Double toDouble(float f) { - return Double.valueOf(f); + return (double) f; } public static Double toDouble(Float f) { - return Double.valueOf(f.doubleValue()); + return f.doubleValue(); + } + + public static Double toDouble(long l) { + return (double) l; + } + + public static Double toDouble(Long l) { + return l.doubleValue(); } /** @@ -2371,8 +2379,8 @@ public static String toString(float f) { public static String toString(Number n) { if (n instanceof BigDecimal) return pf.format(n); if (n instanceof Double) return Caster.toString(n.doubleValue()); - if (n instanceof Float) return Caster.toString(n.floatValue()); if (n instanceof Long) return Caster.toString(n.longValue()); + if (n instanceof Float) return Caster.toString(n.floatValue()); return n.toString(); } From 2a49f5e957240143c13536d3579d66b69ed23180 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 13 Dec 2024 16:12:56 +0100 Subject: [PATCH 07/46] LDEV-5173 improve test --- test/tickets/LDEV5173.cfc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/tickets/LDEV5173.cfc b/test/tickets/LDEV5173.cfc index 8c8193e262..d53bcc6332 100644 --- a/test/tickets/LDEV5173.cfc +++ b/test/tickets/LDEV5173.cfc @@ -4,17 +4,20 @@ component extends = "org.lucee.cfml.test.LuceeTestCase" skip="true" { beforeEach( function(){ variables.startingTZ=getTimeZone(); setTimeZone("IST"); - }); + }); afterEach( function(){ - setTimeZone(variables.startingTZ?:"UTC"); - }); - it( title="parseDateTime with format 'epoch'", body=function( currentSpec ) { - date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epoch" ); + setTimeZone(variables.startingTZ?:"UTC"); + }); + it( title="round trip DateTimeFormat/ParseDateTime with format 'epoch'", body=function( currentSpec ) { + var date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epoch" ); expect(toString(parseDateTime(date=date, format="epoch"))).toBe("{ts '2024-12-11 16:19:54'}"); + expect( parseDateTime( date=date, format="epoch" ) ).toBe( date ); }); - it( title="parseDateTime with format 'epochms'", body=function( currentSpec ) { - date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epochms" ); + + it( title="round trip DateTimeFormat/ParseDateTime with format 'epochms'", body=function( currentSpec ) { + var date = DateTimeFormat( datetime="2024/12/11 16:19:54", mask="epochms" ); expect(toString(parseDateTime(date=date, format="epochms"))).toBe("{ts '2024-12-11 16:19:54'}"); + expect( parseDateTime( date=date, format="epochms" ) ).toBe( date ); }); } ); } From 36984760b862527350ecb4dcd9c23280688fb38a Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 16:36:57 +0100 Subject: [PATCH 08/46] DC-5198 - fix unrelated test case that assumed invalid value --- test/functions/BitOr.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functions/BitOr.cfc b/test/functions/BitOr.cfc index ba7d28eb8c..f0979ecd2a 100644 --- a/test/functions/BitOr.cfc +++ b/test/functions/BitOr.cfc @@ -44,7 +44,7 @@ component extends="org.lucee.cfml.test.LuceeTestCase"{ application action="update" preciseMath=true; expect( BitOr(2147483647, 1) ).toBe(2147483647); application action="update" preciseMath=false; - expect( BitOr(2147483647, 1) ).toBe(2147483648); + expect( BitOr(2147483647, 1) ).toBe(2147483647); }); it("should return the non-zero value when one number is zero", function() { From 6d43add61539f5304a434475a0e53656d03a3314 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 16:50:23 +0100 Subject: [PATCH 09/46] DC-5198 - fix unrelated test case that assumed invalid value --- test/functions/BitSHLN.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functions/BitSHLN.cfc b/test/functions/BitSHLN.cfc index 0c2c507fb5..ebbe09845a 100644 --- a/test/functions/BitSHLN.cfc +++ b/test/functions/BitSHLN.cfc @@ -35,7 +35,7 @@ component extends="org.lucee.cfml.test.LuceeTestCase"{ application action="update" preciseMath=true; assertEquals("4294967294", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) application action="update" preciseMath=false; - assertEquals("4294967296", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) + assertEquals("2147483647", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) }); it(title="Checking BitSHLN() function with negative shift", body = function(currentSpec) { From 587f0b494feafef669cb19030c20ec61f612f437 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Fri, 13 Dec 2024 17:16:07 +0100 Subject: [PATCH 10/46] DC-5198 - fix unrelated test case that assumed invalid value --- test/functions/BitSHLN.cfc | 2 +- test/functions/BitSHRN.cfc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functions/BitSHLN.cfc b/test/functions/BitSHLN.cfc index ebbe09845a..1242c47325 100644 --- a/test/functions/BitSHLN.cfc +++ b/test/functions/BitSHLN.cfc @@ -35,7 +35,7 @@ component extends="org.lucee.cfml.test.LuceeTestCase"{ application action="update" preciseMath=true; assertEquals("4294967294", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) application action="update" preciseMath=false; - assertEquals("2147483647", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) + assertEquals("4294967294", toString(BitSHLN(2147483647, 1))); // 2147483647 << 1 = 0 (overflow) }); it(title="Checking BitSHLN() function with negative shift", body = function(currentSpec) { diff --git a/test/functions/BitSHRN.cfc b/test/functions/BitSHRN.cfc index d637dc384e..e9568fbe63 100644 --- a/test/functions/BitSHRN.cfc +++ b/test/functions/BitSHRN.cfc @@ -35,7 +35,7 @@ component extends="org.lucee.cfml.test.LuceeTestCase"{ application action="update" preciseMath=true; assertEquals("2147483647", BitSHRN(4294967295, 1)); // Large number shifted right application action="update" preciseMath=false; - assertEquals("2147483648", BitSHRN(4294967295, 1)); // Large number shifted right + assertEquals("2147483647", BitSHRN(4294967295, 1)); // Large number shifted right }); it(title="Checking BitSHRN() function with negative numbers", body = function(currentSpec) { From 7051084eb942e1b3ee07f0a9328ab0f28e1c068a Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 13 Dec 2024 22:23:16 +0100 Subject: [PATCH 11/46] LDEV-5200 allow configuring variable name cache max size in KeyImpl https://luceeserver.atlassian.net/browse/LDEV-5200 --- core/src/main/java/lucee/runtime/type/KeyImpl.java | 3 ++- loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/runtime/type/KeyImpl.java b/core/src/main/java/lucee/runtime/type/KeyImpl.java index 2ffb142972..b4e26796f4 100755 --- a/core/src/main/java/lucee/runtime/type/KeyImpl.java +++ b/core/src/main/java/lucee/runtime/type/KeyImpl.java @@ -27,6 +27,7 @@ import java.util.Map; import lucee.commons.digest.WangJenkins; +import lucee.commons.io.SystemUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.engine.ThreadLocalPageContext; import lucee.runtime.exp.CasterException; @@ -46,7 +47,7 @@ public class KeyImpl implements Collection.Key, Castable, Comparable, Externaliz private static final long HSTART = 0xBB40E64DA205B064L; private static final long HMULT = 7664345821815920749L; - private static final int MAX = 5000; + private static final int MAX = Caster.toInteger(SystemUtil.getSystemPropOrEnvVar("lucee.cache.variableKeys", null),5000); // private boolean intern; private String key; diff --git a/loader/build.xml b/loader/build.xml index 5527c4ef94..f260b04f29 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 858c24edbc..9b8a66aa29 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.213-SNAPSHOT + 6.2.0.214-SNAPSHOT jar Lucee Loader Build From 778b10337b6074a099ceeea34d14e56aef52adeb Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Fri, 13 Dec 2024 22:36:48 +0100 Subject: [PATCH 12/46] LDEV-5200 add lucee.cache.variableKeys to sysprop-envar.json --- core/src/main/java/resource/setting/sysprop-envvar.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/resource/setting/sysprop-envvar.json b/core/src/main/java/resource/setting/sysprop-envvar.json index 25ba8c6a70..7a08b49373 100644 --- a/core/src/main/java/resource/setting/sysprop-envvar.json +++ b/core/src/main/java/resource/setting/sysprop-envvar.json @@ -386,5 +386,10 @@ "sysprop": "lucee.scope.arguments.capacity", "envvar": "LUCEE_SCOPE_ARGUMENTS_CAPACITY", "desc": "Sets the initial capacity (size) for the arguments scope hashmap" + }, + { + "sysprop": "lucee.cache.variableKeys", + "envvar": "LUCEE_CACHE_VARIABLEKEYS", + "desc": "Sets the max number of variable names (keys) to cache" } ] \ No newline at end of file From e8fa844dec5fd19c6642e9c862de2389ecdd5427 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Sat, 14 Dec 2024 09:25:52 +0100 Subject: [PATCH 13/46] LDEV-5200 skip cache lookup when lucee.cache.variableKeys is 0 --- core/src/main/java/lucee/runtime/type/KeyImpl.java | 1 + loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/lucee/runtime/type/KeyImpl.java b/core/src/main/java/lucee/runtime/type/KeyImpl.java index b4e26796f4..bc1a526b6c 100755 --- a/core/src/main/java/lucee/runtime/type/KeyImpl.java +++ b/core/src/main/java/lucee/runtime/type/KeyImpl.java @@ -190,6 +190,7 @@ public static Collection.Key init(String key) { * used to inside the rest of the source created, can be dynamic values, so a lot */ public static Collection.Key source(String key) { + if (MAX == 0) return new KeyImpl(key); Key k = keys.get(key); if (k == null) { if (keys.size() > MAX) return new KeyImpl(key); diff --git a/loader/build.xml b/loader/build.xml index f260b04f29..368eb1ff4e 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 9b8a66aa29..afb45f6be9 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.214-SNAPSHOT + 6.2.0.215-SNAPSHOT jar Lucee Loader Build From 381f00336d2094a65321b0622c346d2063f763dd Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Sat, 14 Dec 2024 15:33:14 +0100 Subject: [PATCH 14/46] use an optimal hashmap maxsize for pageSourcePool (767 rather than 1000) --- core/src/main/java/lucee/runtime/PageSourcePool.java | 2 +- loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/runtime/PageSourcePool.java b/core/src/main/java/lucee/runtime/PageSourcePool.java index 7b4cea8059..679943b0c9 100644 --- a/core/src/main/java/lucee/runtime/PageSourcePool.java +++ b/core/src/main/java/lucee/runtime/PageSourcePool.java @@ -51,7 +51,7 @@ public final class PageSourcePool implements Dumpable { // TODO must not be thread safe, is used in sync block only private final Map> pageSources = new ConcurrentHashMap>(); - private int maxSize_min = 1000; + private int maxSize_min = 767; private PageSourcePoolWatcher watcher; private Object token = new SerializableObject(); private MappingImpl mapping; diff --git a/loader/build.xml b/loader/build.xml index 368eb1ff4e..315ba657d3 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index afb45f6be9..4eed6581cb 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.215-SNAPSHOT + 6.2.0.216-SNAPSHOT jar Lucee Loader Build From 09836277e2ee8daa6a0d601fc673fd75e43d5a34 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Sun, 15 Dec 2024 14:17:18 +0100 Subject: [PATCH 15/46] back port performance improvement on felix cache from 7 to 6 --- loader/build.xml | 2 +- loader/pom.xml | 2 +- .../java/lucee/loader/engine/CFMLEngineFactory.java | 11 ----------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/loader/build.xml b/loader/build.xml index 315ba657d3..35a3ff2da1 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 4eed6581cb..35af946d7c 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.216-SNAPSHOT + 6.2.0.217-SNAPSHOT jar Lucee Loader Build diff --git a/loader/src/main/java/lucee/loader/engine/CFMLEngineFactory.java b/loader/src/main/java/lucee/loader/engine/CFMLEngineFactory.java index c5b3f2eeee..92c55fc8a4 100755 --- a/loader/src/main/java/lucee/loader/engine/CFMLEngineFactory.java +++ b/loader/src/main/java/lucee/loader/engine/CFMLEngineFactory.java @@ -288,17 +288,6 @@ public void shutdownFelix() throws BundleException { BundleCollection bc = singelton.getBundleCollection(); if (bc == null || bc.felix == null) return; - - // stop - BundleLoader.removeBundles(bc); - - // we give it some time - try { - Thread.sleep(5000); - } - catch (InterruptedException e) { - } - BundleUtil.stop(felix, false); } From af0560391e5c7eed4278f23378860f0674e9bcff Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Mon, 16 Dec 2024 16:20:51 +0100 Subject: [PATCH 16/46] LDEV-5205 allow configuring LUCEE_THREADS_MAXDEFAULT --- core/src/main/java/lucee/runtime/functions/closure/Each.java | 3 ++- core/src/main/java/resource/setting/sysprop-envvar.json | 5 +++++ loader/build.xml | 2 +- loader/pom.xml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/runtime/functions/closure/Each.java b/core/src/main/java/lucee/runtime/functions/closure/Each.java index a027453cba..f41439fb84 100644 --- a/core/src/main/java/lucee/runtime/functions/closure/Each.java +++ b/core/src/main/java/lucee/runtime/functions/closure/Each.java @@ -53,7 +53,8 @@ public final class Each extends BIF implements ClosureFunc { - public static final int DEFAULT_MAX_THREAD = 20; + public static final int DEFAULT_MAX_THREAD = Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("lucee.threads.maxDefault", null), 20); + private static final long serialVersionUID = 1955185705863596525L; public static String call(PageContext pc, Object obj, UDF udf) throws PageException { diff --git a/core/src/main/java/resource/setting/sysprop-envvar.json b/core/src/main/java/resource/setting/sysprop-envvar.json index 7a08b49373..c1369ccb4a 100644 --- a/core/src/main/java/resource/setting/sysprop-envvar.json +++ b/core/src/main/java/resource/setting/sysprop-envvar.json @@ -391,5 +391,10 @@ "sysprop": "lucee.cache.variableKeys", "envvar": "LUCEE_CACHE_VARIABLEKEYS", "desc": "Sets the max number of variable names (keys) to cache" + }, + { + "sysprop": "lucee.threads.maxDefault", + "envvar": "LUCEE_THREADS_MAXDEFAULT", + "desc": "Sets the default max number of parallel threads, default 20" } ] \ No newline at end of file diff --git a/loader/build.xml b/loader/build.xml index 35a3ff2da1..f43a7b276e 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 35af946d7c..ec9daa3721 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.217-SNAPSHOT + 6.2.0.218-SNAPSHOT jar Lucee Loader Build From f965144ed4ec7d46d66e785586bb1a2a08f98161 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Mon, 16 Dec 2024 16:54:26 +0100 Subject: [PATCH 17/46] LDEV-5203 - fix creating virtual thread --- .../java/lucee/runtime/thread/ThreadUtil.java | 56 +++++++++++++------ loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/lucee/runtime/thread/ThreadUtil.java b/core/src/main/java/lucee/runtime/thread/ThreadUtil.java index 7797bde979..33440f6f85 100755 --- a/core/src/main/java/lucee/runtime/thread/ThreadUtil.java +++ b/core/src/main/java/lucee/runtime/thread/ThreadUtil.java @@ -33,8 +33,10 @@ import javax.servlet.http.HttpSession; import lucee.aprint; +import lucee.print; import lucee.commons.io.DevNullOutputStream; import lucee.commons.io.SystemUtil; +import lucee.commons.io.log.LogUtil; import lucee.commons.io.res.Resource; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.Pair; @@ -54,8 +56,17 @@ public class ThreadUtil { private static final boolean ALLOW_FUTURE_THREADS = false; - private static final Class THREAD_CLASS = Thread.class; + // private static final Class THREAD_CLASS = Thread.class; private static final Class RUNNABLE_CLASS = Runnable.class; + private static Class threadBuilderClass; + private static boolean virtualDisabled = false; + + public static Class getThreadBuilderClass() throws ClassNotFoundException { + if (threadBuilderClass == null) { + threadBuilderClass = Class.forName("java.lang.Thread$Builder$OfVirtual"); + } + return threadBuilderClass; + } // do not change, used in Redis extension public static PageContextImpl clonePageContext(PageContext pc, OutputStream os, boolean stateless, boolean register2Thread, boolean register2RunningThreads) { @@ -205,20 +216,20 @@ public static Thread getThread(Runnable task) { public static Thread getThread(Runnable task, boolean allowVirtual) { if (allowVirtual && SystemUtil.JAVA_VERSION >= SystemUtil.JAVA_VERSION_19) { + try { - // return Thread.ofVirtual().unstarted(task); + // Get Thread.ofVirtual() MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle ofVirtualHandle = lookup.findStatic(THREAD_CLASS, "ofVirtual", MethodType.methodType(THREAD_CLASS.getDeclaredClasses()[0])); - Object builder = ofVirtualHandle.invoke(); - MethodHandle unstartedHandle = lookup.findVirtual(builder.getClass(), "unstarted", MethodType.methodType(THREAD_CLASS, RUNNABLE_CLASS)); - return (Thread) unstartedHandle.invoke(builder, task); + MethodHandle ofVirtualHandle = lookup.findStatic(Thread.class, "ofVirtual", MethodType.methodType(getThreadBuilderClass())); + MethodHandle unstartedHandle = lookup.findVirtual(Class.forName("java.lang.Thread$Builder"), "unstarted", MethodType.methodType(Thread.class, Runnable.class)); + return (Thread) unstartedHandle.bindTo(ofVirtualHandle.invoke()).invoke(task); } catch (Throwable e) { ExceptionUtil.rethrowIfNecessary(e); + LogUtil.log("threading", e); } } return new Thread(task); - } public static ExecutorService createExecutorService(int maxThreads) { @@ -226,21 +237,30 @@ public static ExecutorService createExecutorService(int maxThreads) { } public static ExecutorService createExecutorService(int maxThreads, boolean allowVirtual) { - if (allowVirtual && SystemUtil.JAVA_VERSION >= SystemUtil.JAVA_VERSION_19) { - // FUTURE use newVirtualThreadPerTaskExecutor natively - try { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType methodType = MethodType.methodType(ExecutorService.class); - MethodHandle methodHandle = lookup.findStatic(Executors.class, "newVirtualThreadPerTaskExecutor", methodType); - return (ExecutorService) methodHandle.invoke(); - } - catch (Throwable e) { - ExceptionUtil.rethrowIfNecessary(e); + if (!virtualDisabled) { + if (allowVirtual && SystemUtil.JAVA_VERSION >= SystemUtil.JAVA_VERSION_19) { + // FUTURE use newVirtualThreadPerTaskExecutor natively + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType methodType = MethodType.methodType(ExecutorService.class); + MethodHandle methodHandle = lookup.findStatic(Executors.class, "newVirtualThreadPerTaskExecutor", methodType); + return (ExecutorService) methodHandle.invoke(); + } + catch (Throwable e) { + virtualDisabled = true; + ExceptionUtil.rethrowIfNecessary(e); + LogUtil.log("threading", e); + } } } return Executors.newFixedThreadPool(maxThreads); } + public static void main(String[] args) { + ExecutorService t = createExecutorService(); + print.e(t); + } + public static ExecutorService createExecutorService() { if (SystemUtil.JAVA_VERSION >= SystemUtil.JAVA_VERSION_19) { // FUTURE use newVirtualThreadPerTaskExecutor natively @@ -251,7 +271,9 @@ public static ExecutorService createExecutorService() { return (ExecutorService) methodHandle.invoke(); } catch (Throwable e) { + print.e(e); ExceptionUtil.rethrowIfNecessary(e); + LogUtil.log("threading", e); } } return Executors.newSingleThreadExecutor(); diff --git a/loader/build.xml b/loader/build.xml index 35a3ff2da1..f43a7b276e 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 35af946d7c..ec9daa3721 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.217-SNAPSHOT + 6.2.0.218-SNAPSHOT jar Lucee Loader Build From ba20292b06364075188fad0bd2612ae4514ca2c6 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Mon, 16 Dec 2024 17:16:06 +0100 Subject: [PATCH 18/46] LDEV-5205 add missing import --- core/src/main/java/lucee/runtime/functions/closure/Each.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/lucee/runtime/functions/closure/Each.java b/core/src/main/java/lucee/runtime/functions/closure/Each.java index f41439fb84..ee51b958fd 100644 --- a/core/src/main/java/lucee/runtime/functions/closure/Each.java +++ b/core/src/main/java/lucee/runtime/functions/closure/Each.java @@ -31,6 +31,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import lucee.commons.io.SystemUtil; import lucee.runtime.PageContext; import lucee.runtime.concurrency.Data; import lucee.runtime.concurrency.UDFCaller2; From 4de35cc8df247396098c1ec69730637ae22270a5 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Mon, 16 Dec 2024 20:04:45 +0100 Subject: [PATCH 19/46] clan up --- .../main/java/lucee/runtime/PageContextImpl.java | 13 ------------- .../java/lucee/runtime/functions/closure/Each.java | 3 ++- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/lucee/runtime/PageContextImpl.java b/core/src/main/java/lucee/runtime/PageContextImpl.java index 1f1f903262..e7a8cfb651 100644 --- a/core/src/main/java/lucee/runtime/PageContextImpl.java +++ b/core/src/main/java/lucee/runtime/PageContextImpl.java @@ -2037,19 +2037,6 @@ public Object getFunction(Object coll, String key, Object[] args) throws PageExc @Override public Object getFunction(Object coll, Key key, Object[] args) throws PageException { - if (config.hasDebugOptions(ConfigPro.DEBUG_TEMPLATE) && !gatewayContext) { - DebugEntryTemplate debugEntry = debugger.getEntry(this, getCurrentTemplatePageSource(), key.toString()); - long currTime = getExecutionTime(); - long time = System.nanoTime(); - - Object result = variableUtil.callFunctionWithoutNamedValues(this, coll, key, args); - - long diff = ((System.nanoTime() - time) - (getExecutionTime() - currTime)); - setExecutionTime(getExecutionTime() + diff); - debugEntry.updateExeTime(diff); - - return result; - } return variableUtil.callFunctionWithoutNamedValues(this, coll, key, args); } diff --git a/core/src/main/java/lucee/runtime/functions/closure/Each.java b/core/src/main/java/lucee/runtime/functions/closure/Each.java index f41439fb84..ed00feb20b 100644 --- a/core/src/main/java/lucee/runtime/functions/closure/Each.java +++ b/core/src/main/java/lucee/runtime/functions/closure/Each.java @@ -31,6 +31,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import lucee.commons.io.SystemUtil; import lucee.runtime.PageContext; import lucee.runtime.concurrency.Data; import lucee.runtime.concurrency.UDFCaller2; @@ -54,7 +55,7 @@ public final class Each extends BIF implements ClosureFunc { public static final int DEFAULT_MAX_THREAD = Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("lucee.threads.maxDefault", null), 20); - + private static final long serialVersionUID = 1955185705863596525L; public static String call(PageContext pc, Object obj, UDF udf) throws PageException { From fd773c1a9128b36adeaf987bf2b29652774ef96b Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Mon, 16 Dec 2024 20:09:06 +0100 Subject: [PATCH 20/46] add LogAllThreads --- .../functions/system/LogAllThreads.java | 65 ++++++++++++++++ core/src/main/java/resource/fld/core-base.fld | 76 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 core/src/main/java/lucee/runtime/functions/system/LogAllThreads.java diff --git a/core/src/main/java/lucee/runtime/functions/system/LogAllThreads.java b/core/src/main/java/lucee/runtime/functions/system/LogAllThreads.java new file mode 100644 index 0000000000..e0c3115138 --- /dev/null +++ b/core/src/main/java/lucee/runtime/functions/system/LogAllThreads.java @@ -0,0 +1,65 @@ + +package lucee.runtime.functions.system; + +import java.io.IOException; + +import lucee.commons.io.SystemUtil; +import lucee.commons.io.res.Resource; +import lucee.commons.io.res.util.ResourceUtil; +import lucee.runtime.PageContext; +import lucee.runtime.engine.Controler; +import lucee.runtime.exp.FunctionException; +import lucee.runtime.exp.PageException; +import lucee.runtime.ext.function.Function; +import lucee.runtime.op.Caster; + +public final class LogAllThreads implements Function { + + private static final long serialVersionUID = -1922482127354478506L; + + public static String call(PageContext pc, String path) throws PageException { + return call(pc, path, 0, 10000); + } + + public static String call(PageContext pc, String path, Number interval) throws PageException { + return call(pc, path, interval, 10000); + } + + public static String call(PageContext pc, String path, Number interval, Number duration) throws PageException { + Resource res = ResourceUtil.toResourceNotExisting(pc, path); + if (!res.getParentResource().isDirectory()) + throw new FunctionException(pc, "LogAllThreads", 1, "path", "the directory [" + res.getParent() + "] for your log file [" + path + "] does not exist."); + + int tmp = Caster.toIntValue(interval); + if (tmp < 0) tmp = 10; + final long interv = tmp; + + long ltmp = Caster.toLongValue(duration); + if (ltmp < 1) ltmp = 10000; + final long dur = ltmp; + + long start = System.currentTimeMillis(); + // Create a new thread to run the task + Thread thread = new Thread(() -> { + while (true) { + try { + if ((start + dur) < System.currentTimeMillis()) { + break; + } + // Call the dumpThreadPositions method + Controler.dumpThreadPositions(res); + + // Pause for the specified interval + if (interv > 0) SystemUtil.sleep(interv); + } + catch (IOException e) { + SystemUtil.sleep(1000); + } + } + }); + + // Start the thread + thread.start(); + return null; + } +} \ No newline at end of file diff --git a/core/src/main/java/resource/fld/core-base.fld b/core/src/main/java/resource/fld/core-base.fld index 8b26c2ed87..009ad1cd55 100755 --- a/core/src/main/java/resource/fld/core-base.fld +++ b/core/src/main/java/resource/fld/core-base.fld @@ -9534,6 +9534,82 @@ The following things are considered to be empty: + + + LogAllThreads + lucee.runtime.functions.system.LogAllThreads + system,log,debugging,threads,performance,analysis + + Creates detailed thread stack trace logs in JSONL format for performance analysis and debugging. + This function captures stack traces from all running threads at specified intervals for a given duration. + It executes asynchronously, returning immediately after starting the logging process, making it ideal + for analyzing specific code segments by initiating logging just before the target code execution. + + The output format is JSONL (JSON Lines), where each line represents a separate JSON object containing: + - Timestamp offset in milliseconds from 1/1/1970 00:00:00 UTC (Unix 0) + - Complete stack trace of each thread's current location + + This data can be used for: + - Performance bottleneck identification + - Thread behavior analysis + - Deadlock detection + - Resource usage patterns + + + + path + string + true + + Full file path where the log will be written. The file should have a '.jsonl' extension + for proper identification as a JSON Lines format file. The function will create the file + if it doesn't exist, or append to it if it does. + + Example: "/var/log/lucee/thread_analysis.jsonl" + + + + + interval + number + false + 0 + + The time interval (in milliseconds) between stack trace captures. Lower values provide + more detailed analysis but generate larger log files and may impact performance. + + Recommended ranges: + - 1-10ms: Very detailed analysis, higher overhead + - 10-100ms: Balanced detail and performance + - 100ms+: Lower detail, minimal performance impact + + + + + duration + number + false + 10000 + + Total duration (in milliseconds) for which the function will collect thread data. + After this period, logging automatically stops. + + Common durations: + - 1000-5000ms: Quick snapshots + - 10000ms: Standard analysis period + - 30000ms+: Extended analysis for complex operations + + + + + void + + Returns immediately without waiting for logging completion. The logging process + continues in the background for the specified duration. + + + + lTrim From 954a753435d4237a6b3b8ada7b84350de39f3558 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Tue, 17 Dec 2024 11:23:50 +0100 Subject: [PATCH 21/46] remove startup logging from core (CFMLEngine), it is now in loader --- .../lucee/runtime/engine/CFMLEngineImpl.java | 30 ------------------- .../java/lucee/runtime/engine/Controler.java | 8 +---- loader/build.xml | 2 +- loader/pom.xml | 2 +- 4 files changed, 3 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/lucee/runtime/engine/CFMLEngineImpl.java b/core/src/main/java/lucee/runtime/engine/CFMLEngineImpl.java index f1f988d370..cafb8dd317 100644 --- a/core/src/main/java/lucee/runtime/engine/CFMLEngineImpl.java +++ b/core/src/main/java/lucee/runtime/engine/CFMLEngineImpl.java @@ -223,36 +223,6 @@ public static CFMLEngineFactory FACTORY() { } private CFMLEngineImpl(CFMLEngineFactory factory, BundleCollection bc) { - String dumpPath = Caster.toString(SystemUtil.getSystemPropOrEnvVar("lucee.dump.threads", null), null); - if (!StringUtil.isEmpty(dumpPath, true)) { - int interval = Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("lucee.dump.threads.interval", null), 100); - long start = System.currentTimeMillis(); - long max = Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("lucee.dump.threads.max", null), 10000); - - // Create a new thread to run the task - Thread thread = new Thread(() -> { - while (true) { - try { - if ((start + max) < System.currentTimeMillis()) { - break; - } - // Call the dumpThreadPositions method - Controler.dumpThreadPositions(dumpPath); - - // Pause for the specified interval - SystemUtil.sleep(interval); - } - catch (IOException e) { - e.printStackTrace(); - SystemUtil.sleep(1000); - } - } - }); - - // Start the thread - thread.start(); - } - FACTORY = this.factory = factory; this.bundleCollection = bc; diff --git a/core/src/main/java/lucee/runtime/engine/Controler.java b/core/src/main/java/lucee/runtime/engine/Controler.java index 0122d003b7..187b90879d 100755 --- a/core/src/main/java/lucee/runtime/engine/Controler.java +++ b/core/src/main/java/lucee/runtime/engine/Controler.java @@ -34,7 +34,6 @@ import lucee.commons.io.log.Log; 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.filter.ResourceFilter; import lucee.commons.io.res.util.ResourceUtil; @@ -197,8 +196,7 @@ else if (time > TIMEOUT) { } } - public static void dumpThreadPositions(String path) throws IOException { - Resource target = ResourcesImpl.getFileResourceProvider().getResource(path); + public static void dumpThreadPositions(Resource target) throws IOException { StackTraceElement[] stes; String line; @@ -238,10 +236,6 @@ private static void dumpThreads() { } - public static void main(String[] args) throws IOException { - dumpThreadPositions("/Users/mic/Tmp3/tmp/data.jsonl"); - } - private void control(CFMLFactoryImpl[] factories, boolean firstRun, Log log) { long now = System.currentTimeMillis(); boolean do10Seconds = last10SecondsInterval + 10000 < now; diff --git a/loader/build.xml b/loader/build.xml index f43a7b276e..ee95045d89 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index ec9daa3721..ca74f75ecf 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.218-SNAPSHOT + 6.2.0.219-SNAPSHOT jar Lucee Loader Build From 3f53869dcca8bd4068c918acec4ac4628e52c8ff Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Tue, 17 Dec 2024 11:32:31 +0100 Subject: [PATCH 22/46] improve performance with dynamic invoker --- .../lucee/runtime/reflection/Reflector.java | 23 +-- .../dynamic/DynamicClassLoader.java | 2 +- .../transformer/dynamic/DynamicInvoker.java | 171 +++++++++++++----- .../lucee/transformer/dynamic/meta/Clazz.java | 86 ++++----- .../dynamic/meta/FunctionMember.java | 23 +++ .../dynamic/meta/dynamic/ClazzDynamic.java | 23 +-- .../meta/dynamic/FunctionMemberDynamic.java | 27 +++ .../reflection/FunctionMemberReflection.java | 27 +++ loader/build.xml | 2 +- loader/pom.xml | 2 +- 10 files changed, 263 insertions(+), 123 deletions(-) diff --git a/core/src/main/java/lucee/runtime/reflection/Reflector.java b/core/src/main/java/lucee/runtime/reflection/Reflector.java index 10db76e39a..09e195eed6 100755 --- a/core/src/main/java/lucee/runtime/reflection/Reflector.java +++ b/core/src/main/java/lucee/runtime/reflection/Reflector.java @@ -255,13 +255,13 @@ public static Class[] getClasses(Object[] objs) { public static Class toReferenceClass(Class c) { if (c != null && c.isPrimitive()) { if (c == boolean.class) return Boolean.class; + if (c == int.class) return Integer.class; + if (c == long.class) return Long.class; + if (c == double.class) return Double.class; if (c == byte.class) return Byte.class; if (c == short.class) return Short.class; if (c == char.class) return Character.class; - if (c == int.class) return Integer.class; - if (c == long.class) return Long.class; if (c == float.class) return Float.class; - if (c == double.class) return Double.class; } return c; } @@ -623,14 +623,6 @@ public static ConstructorInstance getConstructorInstance(Class clazz, Object[] a static int count = 0; - public static Object[] cleanArgs(Object[] args) { - if (args == null) { - return new Object[0]; - } - return args; - - } - public static Object[] cleanArgsOld(Object[] args) { if (args == null) { return new Object[0]; @@ -892,6 +884,15 @@ public static void checkAccessibility(Class clazz, Key methodName) { } } + public static void checkAccessibility(Clazz clazz, Key methodName) { + if (methodName.equals(KeyConstants._exit)) { // TODO better implementation + Class cl = clazz.getDeclaringClass(); + if ((cl == System.class || cl == Runtime.class)) { // TODO better implementation + throw new PageRuntimeException(new SecurityException("Calling the exit method is not allowed")); + } + } + } + /* * private static void checkAccesibilityx(Object obj, Key methodName) { * if(methodName.equals(SET_ACCESSIBLE) && obj instanceof Member) { if(true) return; Member diff --git a/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java b/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java index 1eb7af3fa4..8eb89eb923 100644 --- a/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java +++ b/core/src/main/java/lucee/transformer/dynamic/DynamicClassLoader.java @@ -184,7 +184,6 @@ private Class loadClass(String name, boolean resolve, boolean loadFromFS) thr } private Class _loadClass(String name, byte[] barr) { - // print.e(">>>>" + name); Class clazz = defineClass(name, barr, 0, barr.length); if (clazz != null) { loadedClasses.put(name, ""); @@ -273,6 +272,7 @@ public boolean hasClass(String className) { } public boolean isClassLoaded(String className) { + if (loadedClasses.containsKey(className)) return true; return findLoadedClass(className) != null; } diff --git a/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java b/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java index 0874913434..ca2f390596 100644 --- a/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java +++ b/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.io.InputStreamReader; import java.lang.instrument.UnmodifiableClassException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; @@ -31,7 +34,6 @@ import org.objectweb.asm.Type; import lucee.aprint; -import lucee.commons.digest.HashUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.log.Log; import lucee.commons.io.res.Resource; @@ -42,6 +44,7 @@ import lucee.commons.lang.SystemOut; import lucee.loader.engine.CFMLEngineFactory; import lucee.runtime.exp.PageException; +import lucee.runtime.op.Caster; import lucee.runtime.reflection.Reflector; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.KeyImpl; @@ -55,6 +58,7 @@ import lucee.transformer.dynamic.meta.FunctionMember; import lucee.transformer.dynamic.meta.LegacyMethod; import lucee.transformer.dynamic.meta.Method; +import lucee.transformer.dynamic.meta.dynamic.ClazzDynamic; public class DynamicInvoker { @@ -143,28 +147,24 @@ public Clazz getClazz(Class clazz, boolean useReflection) { return Clazz.getClazz(clazz, root, log, useReflection); } - /* - * private static double getClass = 0; private static double match = 0; private static double types - * = 0; private static double getDeclaringClass = 0; private static double lclassPath = 0; private - * static double pathName = 0; private static double clsLoader = 0; private static double - * loadInstance = 0; private static int count = 0; - */ + private static double getClass = 0; + private static double match = 0; + private static double getDeclaringClass = 0; + private static double pathName = 0; + private static double clsLoader = 0; + private static double loadInstance = 0; + public Pair createInstance(Class clazz, Key methodName, Object[] arguments, boolean convertComparsion) throws NoSuchMethodException, IOException, UnmodifiableClassException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, PageException { - /* - * count++; if ((count % 500) == 0) { print.e("-------------------"); print.e("getClass:" + - * getClass); print.e("match:" + match); print.e("types:" + types); print.e("getDeclaringClass:" + - * getDeclaringClass); print.e("lclassPath:" + lclassPath); print.e("pathName:" + pathName); - * print.e("clsLoader:" + clsLoader); print.e("loadInstance:" + loadInstance); } - */ - // double start = SystemUtil.millis(); boolean isConstr = methodName == null; - Clazz clazzz = getClazz(clazz); - - // getClass += (SystemUtil.millis() - start); + // Clazz clazzz = getClazz(clazz); + Clazz clazzz = ClazzDynamic.getInstance(clazz, root, log); + // Clazz clazzz = new ClazzReflection(clazz); + // getClass -= start; // start = SystemUtil.millis(); + // getClass += start; lucee.transformer.dynamic.meta.FunctionMember fm = null; lucee.transformer.dynamic.meta.Method method = null; @@ -176,36 +176,28 @@ public Pair createInstance(Class clazz, Key methodNam // Clazz clazz, final Collection.Key methodName, final Object[] args, boolean convertArgument fm = method = Clazz.getMethodMatch(clazzz, methodName, arguments, true, convertComparsion); } - // match += (SystemUtil.millis() - start); + // match -= start; // start = SystemUtil.millis(); + // match += start; - // types += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); clazz = fm.getDeclaringClass(); // we wanna go as low as possible, to be as open as possible also this avoid not allow to access - // getDeclaringClass += (SystemUtil.millis() - start); + // getDeclaringClass -= start; // start = SystemUtil.millis(); + // getDeclaringClass += start; - StringBuilder sbClassPath = new StringBuilder(); - sbClassPath.append(clazz.getName().replace('.', '/')).append('/').append(isConstr ? "____init____" : fm.getName()); - if (fm.getArgumentCount() > 0) { - StringBuilder sbArgs = new StringBuilder(); - for (String arg: fm.getArguments()) { - sbArgs.append(':').append(arg); - } - sbClassPath.append('_').append(HashUtil.create64BitHashAsString(sbArgs, Character.MAX_RADIX)); - } - // lclassPath += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); + String className = fm.getClassName(); - String classPath = Clazz.getPackagePrefix() + sbClassPath.toString();// StringUtil.replace(sbClassPath.toString(), "javae/lang/", "java_lang/", false); - String className = classPath.replace('/', '.'); - - // pathName += (SystemUtil.millis() - start); + // pathName -= start; // start = SystemUtil.millis(); + // pathName += start; + DynamicClassLoader loader = getCL(clazz); - // clsLoader += (SystemUtil.millis() - start); + + // clsLoader -= start; // start = SystemUtil.millis(); + // clsLoader += start; + if (loader.hasClass(className)) { try { return new Pair(fm, loader.loadInstance(className)); @@ -215,9 +207,9 @@ public Pair createInstance(Class clazz, Key methodNam // simply ignore when fail } // finally { - // loadInstance += (SystemUtil.millis() - start); + // loadInstance -= start; // start = SystemUtil.millis(); - + // loadInstance += start; // } } synchronized (SystemUtil.createToken("dyninvocer", className)) { @@ -226,7 +218,7 @@ public Pair createInstance(Class clazz, Key methodNam ClassWriter cw = ASMUtil.getClassWriter(); MethodVisitor mv; String abstractClassPath = "java/lang/Object"; - cw.visit(ASMUtil.getJavaVersionForBytecodeGeneration(), Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classPath, + cw.visit(ASMUtil.getJavaVersionForBytecodeGeneration(), Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, fm.getClassPath(), "Ljava/lang/Object;Ljava/util/function/BiFunction;", "java/lang/Object", new String[] { "java/util/function/BiFunction" }); // Constructor @@ -428,12 +420,109 @@ public static Type[] getArgumentTypes(Constructor constructor) { return Type.getArgumentTypes(descriptor.toString()); } - public static void main(String[] args) throws Exception { + public static class TestMule { + public void test(int x) { + + } + } + + public Pair createInstance2(Class clazz, Key methodName, Object[] arguments, boolean convertComparsion) { + + return null; + } + + public static void main(String[] args) throws Throwable { System.setProperty("lucee.allow.reflection", "false"); Resource classes = ResourcesImpl.getFileResourceProvider().getResource("/Users/mic/tmp8/classes/"); ResourceUtil.deleteContent(classes, null); DynamicInvoker e = new DynamicInvoker(classes); + DynamicInvoker.getInstance(classes); + { + int rounds = 6; + int max = 500000; + long dynamicInvoker = Long.MAX_VALUE; + long dynamicInvoker2 = Long.MAX_VALUE; + long reflection = Long.MAX_VALUE; + long direct = Long.MAX_VALUE; + long methodHandle = Long.MAX_VALUE; + long tmp; + TestMule tm = new TestMule(); + Class clazz = tm.getClass(); + Class[] cargs = new Class[] { int.class }; + // reflection + for (int i = 0; i < rounds; i++) { + long start = System.currentTimeMillis(); + for (int y = 0; y < max; y++) { + clazz.getMethod("test", cargs).invoke(tm, new Object[] { 1 }); + } + tmp = System.currentTimeMillis() - start; + if (tmp < reflection) reflection = tmp; + } + + // invokeInstanceMethod + for (int i = 0; i < rounds; i++) { + long start = System.currentTimeMillis(); + for (int y = 0; y < max; y++) { + e.invokeInstanceMethod(tm, "test", new Object[] { 1 }, false); + } + tmp = System.currentTimeMillis() - start; + if (tmp < dynamicInvoker) dynamicInvoker = tmp; + } + + // invokeInstanceMethod + for (int i = 0; i < rounds; i++) { + long start = System.currentTimeMillis(); + for (int y = 0; y < max; y++) { + Reflector.getMethod(clazz, "test", cargs).invoke(tm, new Object[] { 1 }); + } + tmp = System.currentTimeMillis() - start; + if (tmp < dynamicInvoker2) dynamicInvoker2 = tmp; + } + + // MethodHandles + MethodHandles.Lookup lookup = MethodHandles.lookup(); + for (int i = 0; i < rounds; i++) { + long start = System.currentTimeMillis(); + for (int y = 0; y < max; y++) { + MethodType methodType = MethodType.methodType(void.class, int.class); + MethodHandle testHandle = lookup.findVirtual(clazz, "test", methodType); + testHandle.invoke(tm, 1); + + } + tmp = System.currentTimeMillis() - start; + if (tmp < methodHandle) methodHandle = tmp; + } + + // direct + for (int i = 0; i < rounds; i++) { + long start = System.currentTimeMillis(); + for (int y = 0; y < max; y++) { + tm.test(1); + } + tmp = System.currentTimeMillis() - start; + if (tmp < direct) direct = tmp; + } + + aprint.e("dynamicInvoker2:" + dynamicInvoker2); + aprint.e("dynamicInvoker:" + dynamicInvoker); + aprint.e("reflection:" + reflection); + aprint.e("methodHandle:" + reflection); + aprint.e("direct:" + direct); + + aprint.e("-------------------"); + double total = getClass + match + getDeclaringClass + pathName + clsLoader + loadInstance; + + aprint.e(((int) getClass) + ":" + Caster.toIntValue(100d / total * getClass) + "% :getClass"); + aprint.e(((int) match) + ":" + Caster.toIntValue(100d / total * match) + "% :match"); + aprint.e(((int) getDeclaringClass) + ":" + Caster.toIntValue(100d / total * getDeclaringClass) + "% :getDeclaringClass"); + aprint.e(((int) pathName) + ":" + Caster.toIntValue(100d / total * pathName) + "% :pathName"); + aprint.e(((int) clsLoader) + ":" + Caster.toIntValue(100d / total * clsLoader) + "% :clsLoader"); + aprint.e(((int) loadInstance) + ":" + Caster.toIntValue(100d / total * loadInstance) + "% :loadInstance"); + + if (true) return; + } + { List methods; diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/Clazz.java b/core/src/main/java/lucee/transformer/dynamic/meta/Clazz.java index 2d19d8b06d..369ebdbd1c 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/Clazz.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/Clazz.java @@ -57,7 +57,7 @@ public abstract class Clazz implements Serializable { public abstract Type getDeclaringType(); - protected abstract String id(); + public abstract String id(); public static boolean allowReflection() { if (allowReflection == null) { @@ -86,7 +86,6 @@ public static Clazz getClazz(Class clazz, Resource root, Log log) { } } - private static Map>> cachedMethods = new ConcurrentHashMap<>(); private static RefInteger nirvana = new RefIntegerImpl(); /* @@ -96,61 +95,20 @@ public static Clazz getClazz(Class clazz, Resource root, Log log) { * private static double lclasses2 = 0; private static int count = 0; */ + private static Map>> cachedMethods = new ConcurrentHashMap<>(); + public static Method getMethodMatch(Clazz clazz, final Collection.Key methodName, Object[] args, boolean convertArgument, boolean convertComparsion) throws NoSuchMethodException, IOException, PageException { - /* - * count++; if ((count % 500) == 0) { print.e("-------------------"); print.e("cleanArgs:" + - * cleanArgs); print.e("checkAccessibility:" + checkAccessibility); print.e("lmethods:" + lmethods); - * print.e("cache:" + cache); print.e("exact:" + exact); print.e("like:" + like); print.e("convert:" - * + convert); print.e("lclasses:" + lclasses); print.e("lclasses2:" + lclasses2); } double start = - * SystemUtil.millis(); - */ - - args = Reflector.cleanArgs(args); - - // cleanArgs += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); List methods = clazz.getMethods(methodName.getString(), false, args.length); - - // lmethods += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); - if (methods != null && methods.size() > 0) { - Class[] clazzArgs = Reflector.getClasses(args); - - // cache - StringBuilder sb = new StringBuilder(clazz.id()).append(methodName).append(';'); - for (Class cls: clazzArgs) { - sb.append(cls.getName()).append(';'); - } - - String key = sb.toString(); - - // get match from cache - SoftReference> sr = cachedMethods.get(key); - if (sr != null) { - Pair p = sr.get(); - if (p != null) { - // print.e("used cached match(" + p.getValue() + "):" + key + ":" + cachedMethods.size()); - // convert arguments - if (p.getValue()) { - // print.e("------- " + clazz.getDeclaringClass().getName() + ":" + methodName + " -----"); - Class[] trgArgs = p.getName().getArgumentClasses(); - for (int x = 0; x < trgArgs.length; x++) { - if (args[x] != null) args[x] = Reflector.convert(args[x], Reflector.toReferenceClass(trgArgs[x]), nirvana); - } - } - return p.getName(); - } + if (args.length == 0) { + return methods.get(0); } - // cache += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); - Reflector.checkAccessibility(clazz.getDeclaringClass(), methodName); + Class[] clazzArgs = Reflector.getClasses(args); - // checkAccessibility += (SystemUtil.millis() - start); - // start = SystemUtil.millis(); + Reflector.checkAccessibility(clazz, methodName); // exact comparsion outer: for (Method m: methods) { @@ -159,8 +117,6 @@ public static Method getMethodMatch(Clazz clazz, final Collection.Key methodName for (int y = 0; y < parameterTypes.length; y++) { if (Reflector.toReferenceClass(parameterTypes[y]) != clazzArgs[y]) continue outer; } - // print.e("exact match:" + key + ":"); - cachedMethods.put(key, new SoftReference>(new Pair(m, Boolean.FALSE))); return m; } } @@ -174,14 +130,36 @@ public static Method getMethodMatch(Clazz clazz, final Collection.Key methodName for (int y = 0; y < parameterTypes.length; y++) { if (!Reflector.like(clazzArgs[y], Reflector.toReferenceClass(parameterTypes[y]))) continue outer; } - // print.e("like match:" + key + ":"); - cachedMethods.put(key, new SoftReference>(new Pair(m, Boolean.FALSE))); return m; } } // like += (SystemUtil.millis() - start); // start = SystemUtil.millis(); + // cache + StringBuilder sb = new StringBuilder(100).append(clazz.id()).append(methodName).append(';'); + for (Class cls: clazzArgs) { + sb.append(cls.getName()).append(';'); + } + String key = sb.toString(); + + // get match from cache + SoftReference> sr = cachedMethods.get(key); + if (sr != null) { + Pair p = sr.get(); + if (p != null) { + // print.e("used cached match(" + p.getValue() + "):" + key + ":" + cachedMethods.size()); + // convert arguments + if (p.getValue()) { + Class[] trgArgs = p.getName().getArgumentClasses(); + for (int x = 0; x < trgArgs.length; x++) { + if (args[x] != null) args[x] = Reflector.convert(args[x], Reflector.toReferenceClass(trgArgs[x]), nirvana); + } + } + return p.getName(); + } + } + // convert comparsion Pair result = null; int _rating = 0; @@ -309,7 +287,6 @@ else if (trgClassLoader != null) { } public static Constructor getConstructorMatch(Clazz clazz, Object[] args, boolean convertArgument, boolean convertComparsion) throws NoSuchMethodException, IOException { - args = Reflector.cleanArgs(args); List constructors = clazz.getConstructors(args.length); if (constructors != null && constructors.size() > 0) { Class[] clazzArgs = Reflector.getClasses(args); @@ -488,4 +465,5 @@ public static Class toClass(ClassLoader cl, Type type) throws ClassException { public static String getPackagePrefix() { return "lucee/invoc/wrap/v" + VERSION + "/"; } + } \ No newline at end of file diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java b/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java index 269105cc56..3687118e9b 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java @@ -4,6 +4,8 @@ import org.objectweb.asm.Type; +import lucee.commons.digest.HashUtil; + public interface FunctionMember extends Serializable { public abstract String getName(); @@ -48,4 +50,25 @@ public interface FunctionMember extends Serializable { public abstract boolean inInterface(); + public abstract String getClassPath(); + + public abstract String getClassName(); + + public static String createClassPath(FunctionMember fm) { + StringBuilder sbClassPath = new StringBuilder(); + // sbClassPath.append(getDeclaringClassName().replace('.', '/')).append('/').append(isConstr ? + // "____init____" : fm.getName()); + sbClassPath.append(fm.getDeclaringClassName().replace('.', '/')).append('/'); + if (fm.getName() == null) sbClassPath.append("____init____"); + else sbClassPath.append(fm.getName()); + + if (fm.getArgumentCount() > 0) { + StringBuilder sbArgs = new StringBuilder(); + for (String arg: fm.getArguments()) { + sbArgs.append(':').append(arg); + } + sbClassPath.append('_').append(HashUtil.create64BitHashAsString(sbArgs, Character.MAX_RADIX)); + } + return Clazz.getPackagePrefix() + sbClassPath.toString(); + } } diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java index d82673cfc8..73f2beaf76 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java @@ -54,6 +54,7 @@ public class ClazzDynamic extends Clazz { private final FunctionMember[] declaredConstructors; private String clid; + private String id; private static Map clids = new IdentityHashMap<>(); private static String systemId; @@ -68,17 +69,9 @@ public class ClazzDynamic extends Clazz { */ public static ClazzDynamic getInstance(Class clazz, Resource dir, Log log) throws IOException { - - /* - * count++; if ((count % 500) == 0) { print.e("-------------------"); - * print.e("generateClassLoderId:" + generateClassLoderId); print.e("path:" + path); - * print.e("isFile:" + isFile); print.e("deserialize:" + deserialize); print.e("put:" + put); - * print.e("neww:" + neww); print.e("serialize:" + serialize); print.e("done:" + done); } double - * start = SystemUtil.millis(); - */ - ClazzDynamic cd = null; Reference sr = classes.get(clazz); + if (sr == null || (cd = sr.get()) == null) { synchronized (clazz) { sr = classes.get(clazz); @@ -223,11 +216,13 @@ public Type getDeclaringType() { @Override public String id() { - if (clid == null) { - clid = generateClassLoderId(clazz); + if (id == null) { + if (clid == null) { + clid = generateClassLoderId(clazz); + } + id = clid + ":" + clazz.getName(); } - - return clid + ":" + clazz.getName(); + return id; } @Override @@ -304,7 +299,7 @@ public List getMethods(String methodName, boolean nameCaseSensitive, int for (FunctionMember fm: methods) { if (/* fm.isPublic() && */ - (argumentLength < 0 || argumentLength == fm.getArgumentCount()) && + (argumentLength == fm.getArgumentCount() || argumentLength < 0) && (methodName == null || (nameCaseSensitive ? methodName.equals(fm.getName()) : methodName.equalsIgnoreCase(fm.getName()))) diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/FunctionMemberDynamic.java b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/FunctionMemberDynamic.java index 6195d50a11..0ac5e4daf7 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/FunctionMemberDynamic.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/FunctionMemberDynamic.java @@ -48,6 +48,9 @@ abstract class FunctionMemberDynamic implements FunctionMember { protected transient Type[] expTypes; protected transient String[] expNames; + private String classPath; + private String className; + public FunctionMemberDynamic(String name) { this.name = name; } @@ -489,4 +492,28 @@ public String toString() { return sb.toString(); } + @Override + public String getClassPath() { + if (classPath == null) { + synchronized (this) { + if (classPath == null) { + classPath = FunctionMember.createClassPath(this); + } + } + } + return classPath; + } + + @Override + public String getClassName() { + if (className == null) { + synchronized (this) { + if (className == null) { + className = getClassPath().replace('/', '.'); + } + } + } + return className; + } + } diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/reflection/FunctionMemberReflection.java b/core/src/main/java/lucee/transformer/dynamic/meta/reflection/FunctionMemberReflection.java index 47c593bb9d..81470555b2 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/reflection/FunctionMemberReflection.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/reflection/FunctionMemberReflection.java @@ -11,6 +11,8 @@ abstract class FunctionMemberReflection implements FunctionMember { private static final long serialVersionUID = 6812458458981023205L; private Executable executable; + private String classPath; + private String className; public FunctionMemberReflection(Executable method) { this.executable = method; @@ -147,4 +149,29 @@ public String[] getExceptions() { public String toString() { return executable.toString(); } + + @Override + public String getClassPath() { + if (classPath == null) { + synchronized (this) { + if (classPath == null) { + classPath = FunctionMember.createClassPath(this); + } + } + } + return classPath; + } + + @Override + public String getClassName() { + if (className == null) { + synchronized (this) { + if (className == null) { + className = getClassPath().replace('/', '.'); + } + } + } + return className; + } + } diff --git a/loader/build.xml b/loader/build.xml index ee95045d89..4549164558 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index ca74f75ecf..1976f426f4 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.219-SNAPSHOT + 6.2.0.220-SNAPSHOT jar Lucee Loader Build From 7b92f77644b71814590bbafd8bfa393739a1fac0 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Tue, 17 Dec 2024 13:10:06 +0100 Subject: [PATCH 23/46] improve the exception created --- .../main/java/lucee/commons/lang/ExceptionUtil.java | 3 +++ .../lucee/runtime/exp/PageRuntimeException.java | 13 ++----------- .../library/function/FunctionLibFunction.java | 2 +- loader/build.xml | 2 +- loader/pom.xml | 2 +- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/lucee/commons/lang/ExceptionUtil.java b/core/src/main/java/lucee/commons/lang/ExceptionUtil.java index f110d4f284..20fe40f5bb 100644 --- a/core/src/main/java/lucee/commons/lang/ExceptionUtil.java +++ b/core/src/main/java/lucee/commons/lang/ExceptionUtil.java @@ -27,6 +27,7 @@ import java.util.Arrays; import java.util.Iterator; +import lucee.print; import lucee.commons.io.SystemUtil.TemplateLine; import lucee.commons.io.res.Resource; import lucee.commons.io.res.util.ResourceUtil; @@ -325,6 +326,8 @@ public static void initCauseEL(Throwable e, Throwable cause) { e.initCause(cause); } catch (Exception ex) { + print.e("xxxxxxxxxxxx"); + print.e(ex); } } diff --git a/core/src/main/java/lucee/runtime/exp/PageRuntimeException.java b/core/src/main/java/lucee/runtime/exp/PageRuntimeException.java index 549cf03eba..b8746fbe49 100644 --- a/core/src/main/java/lucee/runtime/exp/PageRuntimeException.java +++ b/core/src/main/java/lucee/runtime/exp/PageRuntimeException.java @@ -18,6 +18,7 @@ **/ package lucee.runtime.exp; +import lucee.commons.lang.ExceptionUtil; import lucee.runtime.PageContext; import lucee.runtime.PageSource; import lucee.runtime.config.Config; @@ -41,17 +42,7 @@ public class PageRuntimeException extends RuntimeException implements IPageExcep public PageRuntimeException(Throwable t) { super(t.getMessage(), t); this.pe = Caster.toPageException(t); - } - - /** - * constructor of the class - * - * @param pe page exception to hold - */ - public PageRuntimeException(PageException pe) { - super(pe.getMessage(), pe); - setStackTrace(pe.getStackTrace()); - this.pe = pe; + ExceptionUtil.initCauseEL(this, t); } /** diff --git a/core/src/main/java/lucee/transformer/library/function/FunctionLibFunction.java b/core/src/main/java/lucee/transformer/library/function/FunctionLibFunction.java index cd92592b9e..24e0655bcc 100755 --- a/core/src/main/java/lucee/transformer/library/function/FunctionLibFunction.java +++ b/core/src/main/java/lucee/transformer/library/function/FunctionLibFunction.java @@ -428,7 +428,7 @@ public BIF getBIF() { } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); - throw new RuntimeException(t); + throw new PageRuntimeException(t); } } else { diff --git a/loader/build.xml b/loader/build.xml index 4549164558..bac1c48504 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 1976f426f4..79f7ecd567 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.220-SNAPSHOT + 6.2.0.221-SNAPSHOT jar Lucee Loader Build From 9b3b2d1cd6fafd1c2b037d7408b862cfea038ab7 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Tue, 17 Dec 2024 13:34:11 +0100 Subject: [PATCH 24/46] no message --- .../java/lucee/transformer/dynamic/meta/FunctionMember.java | 3 ++- loader/build.xml | 2 +- loader/pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java b/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java index 3687118e9b..3d1ba554b7 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/FunctionMember.java @@ -59,7 +59,8 @@ public static String createClassPath(FunctionMember fm) { // sbClassPath.append(getDeclaringClassName().replace('.', '/')).append('/').append(isConstr ? // "____init____" : fm.getName()); sbClassPath.append(fm.getDeclaringClassName().replace('.', '/')).append('/'); - if (fm.getName() == null) sbClassPath.append("____init____"); + + if (fm instanceof Constructor) sbClassPath.append("____init____"); else sbClassPath.append(fm.getName()); if (fm.getArgumentCount() > 0) { diff --git a/loader/build.xml b/loader/build.xml index bac1c48504..76046476e0 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 79f7ecd567..74f42f6f94 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.221-SNAPSHOT + 6.2.0.222-SNAPSHOT jar Lucee Loader Build From 203b87e021974936c9d81391e346d82f0924006d Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Tue, 17 Dec 2024 13:56:26 +0100 Subject: [PATCH 25/46] build: add support for -DFlightRecording="true" --- ant/build-core.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ant/build-core.xml b/ant/build-core.xml index 47d9c682e5..64dd2f7e3c 100644 --- a/ant/build-core.xml +++ b/ant/build-core.xml @@ -647,6 +647,8 @@ + +