Skip to content

Commit

Permalink
LDEV-5185 - fix overlap issue
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Dec 10, 2024
1 parent ce19f78 commit 5dca99c
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 26 deletions.
50 changes: 35 additions & 15 deletions core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,28 +435,47 @@ public static void main(String[] args) throws Exception {
DynamicInvoker e = new DynamicInvoker(classes);

{
DynamicInvoker.getInstance(classes);
List<Method> methods = Reflector.getMethods(lucee.runtime.config.ConfigServerImpl.class);
methods = Reflector.getMethods(lucee.runtime.config.ConfigWebImpl.class);
List<Method> methods;

aprint.e("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
for (Method method: methods) {
if (!method.getName().startsWith("reset") || method.getName().equals("reset") || method.getName().equals("resetAll") || method.getArgumentCount() != 0) continue;
aprint.e("->" + method.getDeclaringProviderClassNameWithSameAccess() + ":" + method.getDeclaringProviderClassName() + ":" + method.getName()); // if (--max == 0)
// break; } }
}
DynamicInvoker.getInstance(classes);
// methods = Reflector.getMethods(lucee.runtime.config.ConfigWebImpl.class);
// methods = Reflector.getMethods(lucee.runtime.PageContextImpl.class);
List<Method> methodsw = Reflector.getMethods(lucee.runtime.config.ConfigWebImpl.class);

// methods = Reflector.getMethods(lucee.runtime.config.ConfigServerImpl.class);
methods = Reflector.getMethods(lucee.runtime.config.ConfigServerImpl.class);
// methods = Reflector.getMethods(lucee.runtime.config.ConfigImpl.class);
// methods = Reflector.getMethods(lucee.runtime.config.ConfigWebPro.class);

// methods = Reflector.getMethods(lucee.runtime.config.ConfigServerImpl.class);

int max = 5;
aprint.e("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
// int max = 500;
aprint.e("xxxxxxxxxxxxxxxx ConfigServerImpl xxxxxxxxxxxxxxxxx");
for (Method method: methods) {
if (!method.getName().startsWith("reset") || method.getName().equals("reset") || method.getName().equals("resetAll") || method.getArgumentCount() != 0) continue;
aprint.e("->" + method.getDeclaringProviderClassNameWithSameAccess() + ":" + method.getDeclaringProviderClassName() + ":" + method.getName()); // if (--max == 0)
// break; } }
// if (!method.getName().startsWith("reset") || method.getName().equals("reset") ||
// method.getName().equals("resetAll") || method.getArgumentCount() != 0) continue;
if (method.getDeclaringProviderClassNameWithSameAccess().indexOf("ConfigWeb") != -1) {
aprint.e("->" + method.getDeclaringProviderClassNameWithSameAccess() + ":"

+ method.getDeclaringProviderClassName() + ":" + method.getDeclaringClassName() + ":" + method.getName());
// throw new RuntimeException("ups!");
// if (--max == 0) break;
}
}
aprint.e("xxxxxxxxxxxxxxxx ConfigWebImpl xxxxxxxxxxxxxxxxx");
for (Method method: methodsw) {
// if (!method.getName().startsWith("reset") || method.getName().equals("reset") ||
// method.getName().equals("resetAll") || method.getArgumentCount() != 0) continue;
if (method.getDeclaringProviderClassNameWithSameAccess().indexOf("ConfigServer") != -1) {
aprint.e("->" + method.getDeclaringProviderClassNameWithSameAccess() + ":"

+ method.getDeclaringProviderClassName() + ":" + method.getDeclaringClassName() + ":" + method.getName());
// throw new RuntimeException("ups!");
// if (--max == 0) break;
}
}
}

/// if (true) return;
HashMap map = new HashMap<>();
map.put("aaa", "sss");
Iterator it = map.keySet().iterator();
Expand Down Expand Up @@ -579,6 +598,7 @@ public static void main(String[] args) throws Exception {
aprint.e(e.invokeInstanceMethod(sb, "toSTring", new Object[] {}, false));
aprint.e(e.invokeStaticMethod(SystemUtil.class, "getSystemPropOrEnvVar", new Object[] { "a.b.c", "default-value" }, true));
aprint.e(e.invokeStaticMethod(ListUtil.class, "arrayToList", new Object[] { new String[] { "a", "b" }, "," }, true));
aprint.e("done");

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public static String generateClassLoderId(Class<?> clazz) {
private ClazzDynamic(Class clazz, String clid, Log log) throws IOException {
this.clazz = clazz;
this.clid = clid;
Map<String, FunctionMember> members = _getFunctionMembers(null, this.clid, clazz, log);
Map<String, FunctionMember> members = getFunctionMembers(this.clid, clazz, log);

LinkedList<FunctionMember> tmpMethods = new LinkedList<>();
LinkedList<FunctionMember> tmpDeclaredMethods = new LinkedList<>();
Expand Down Expand Up @@ -365,18 +365,31 @@ public List<Constructor> getDeclaredConstructors(int argumentLength) throws IOEx
return list;
}

private static Map<String, FunctionMember> _getFunctionMembers(Map<String, FunctionMember> inputMembers, String clid, final Class clazz, Log log) throws IOException {
String key = clid + ":" + clazz.getName();
if (inputMembers == null) inputMembers = new LinkedHashMap<>();
final Map<String, FunctionMember> members = inputMembers;
Map<String, FunctionMember> existing = membersCollection.get(key);
private static Map<String, FunctionMember> getFunctionMembers(String clid, final Class clazz, Log log) throws IOException {
return _getFunctionMembers(clid, clazz, log);
}

private static Map<String, FunctionMember> _getFunctionMembers(String clid, final Class clazz, Log log) throws IOException {

final Map<String, FunctionMember> members = new LinkedHashMap<>();
Map<String, FunctionMember> existing = membersCollection.get(clazz);

if (existing != null) {
/*
* if (true) { print.e("ex-->" + clazz.getName()); for (Entry<String, FunctionMember> e:
* existing.entrySet()) { if (e.getValue().getDeclaringClass() != clazz &&
* !Reflector.isInstaneOf(clazz, e.getValue().getDeclaringClass(), true) &&
* e.getValue().getDeclaringClass() != Object.class) print.e("- " + e.getValue()); }
*
* }
*/

for (Entry<String, FunctionMember> e: existing.entrySet()) {
members.put(e.getKey(), e.getValue());
}
return members;
}
// print.e("ne-->" + clazz.getName());

final String classPath = clazz.getName().replace('.', '/') + ".class";
final ClassLoader cl = getClassLoader(clazz);
Expand All @@ -401,18 +414,153 @@ private static Map<String, FunctionMember> _getFunctionMembers(Map<String, Funct
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
classAccess.setValue(access);
if (superName != null) {
try {
// add(members, _getFunctionMembers(clid,
// cl.loadClass(ASMUtil.getClassName(Type.getObjectType(superName))), log));
add(members, _getFunctionMembers(clid, cl.loadClass(ASMUtil.getClassName(Type.getObjectType(superName))), log));
}
catch (IllegalArgumentException iae) {
String v = ASMUtil.getJavaVersionFromException(iae, null);
if (v != null) {
throw new RuntimeException("The class [" + superName + "] was compiled with Java version [" + v + "], "
+ "which is not supported by the current version of ASM. The highest supported version is ["
+ ASMUtil.toStringVersionFromBytceodeVersion(ASMUtil.getMaxVersion(), "unknown") + "]. ");

}
throw iae;
}
catch (RuntimeException re) {
throw re;
}
catch (Exception e) {
if (log != null) log.error("dynamic", e);
}
}
if (interfaces != null && interfaces.length > 0) {
for (String interf: interfaces) {
try {
// add(members, _getFunctionMembers(clid,
// cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log));
_getFunctionMembers(members, clid, cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log);
add(members, _getFunctionMembers(clid, cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log));
}
catch (Exception e) {
if (log != null) log.error("dynamic", e);
}
}
}
// print.e("-- " + name);
// print.e(members);

super.visit(version, access, name, signature, superName, interfaces);
}

private void add(Map<String, FunctionMember> members, Map<String, FunctionMember> add) {
for (Entry<String, FunctionMember> e: add.entrySet()) {
members.put(e.getKey(), e.getValue());
}
}

@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {

FunctionMemberDynamic fmCurrent = FunctionMemberDynamic.createInstance(clazz, name, access, descriptor, exceptions, classAccess.toInt());
String id = Clazz.id(fmCurrent);
// if (name.toLowerCase().indexOf("next") != -1 && name.toLowerCase().indexOf("node") == -1) {
// print.e("======>" + clazz.getName() + ":" + name);
// print.e(members.keySet());
// }
FunctionMember parent = members.get(id);
if (parent instanceof FunctionMemberDynamic) {
FunctionMemberDynamic fmParent = (FunctionMemberDynamic) parent;
// java.lang.Appendable

Class tmpClass = fmParent.getDeclaringProviderClass(true);
if (tmpClass != null) {
Class rtnClass = null;
if (fmParent instanceof Method) {

Class tmpRtn = fmParent.getDeclaringProviderRtnClass(true);
rtnClass = tmpRtn;
}

/*
* if (name.equals("toLocalDateTime")) { print.e("xxxxxxxxxxxxxxx"); print.e(clazz + ":" + name +
* ":" + descriptor); // print.e(Clazz.getAccessModifier(fmCurrent)); //
* print.e(Clazz.getAccessModifier(fmParent)); print.e("curr: " +
* Clazz.getAccessModifierAsString(fmCurrent)); print.e("parr: " +
* Clazz.getAccessModifierAsString(fmParent)); print.e("DeclaringClassName: " +
* fmCurrent.getDeclaringClassName()); print.e("getDeclaringProviderClassName: " +
* fmCurrent.getDeclaringProviderClassNameWithSameAccess()); // print.e("-----------------" +
* Clazz.compareAccess(fmd, fm)); }
*/

Type tmpType = tmpClass != null ? Type.getType(tmpClass) : null;
Type rtnType = rtnClass != null ? Type.getType(rtnClass) : null;

if (Clazz.compareAccess(fmParent, fmCurrent) >= 0) fmCurrent.setDeclaringProviderClassWithSameAccess(tmpClass, tmpType, rtnClass, rtnType);
fmCurrent.setDeclaringProviderClass(tmpClass, tmpType, rtnClass, rtnType);

/*
* if (name.equals("nextElement")) { print.e(fm.getDeclaringProviderClassName());
* print.e(fm.getDeclaringProviderClassNameWithSameAccess()); }
*/
}
}
members.put(id, fmCurrent);

return super.visitMethod(access, name, descriptor, signature, exceptions);
}
};
// Start visiting the class
classReader.accept(visitor, 0);
membersCollection.put(clazz, cloneIt(members));
return members;
}

private static Map<String, FunctionMember> _getFunctionMembers(Map<String, FunctionMember> inputMembers, String clid, final Class clazz, Log log) throws IOException {
String key = clid + ":" + clazz.getName();

// print.e("-->" + clazz.getName());
// if (inputMembers != null) {
// if (inputMembers.size() < 20) print.e(inputMembers.keySet());
// else print.e(inputMembers.size());
// }

if (inputMembers == null) inputMembers = new LinkedHashMap<>();
final Map<String, FunctionMember> members = inputMembers;
Map<String, FunctionMember> existing = membersCollectionOld.get(key);

if (existing != null) {
for (Entry<String, FunctionMember> e: existing.entrySet()) {
members.put(e.getKey(), e.getValue());
}
return members;
}

final String classPath = clazz.getName().replace('.', '/') + ".class";
final ClassLoader cl = getClassLoader(clazz);
final RefInteger classAccess = new RefIntegerImpl();
ClassReader classReader;

try {
classReader = new ClassReader(cl.getResourceAsStream(classPath));
}
catch (IOException ioe) {
if ("Class not found".equals(ioe.getMessage())) {
IOException tmp = new IOException("unable to load class path [" + classPath + "]");
ExceptionUtil.initCauseEL(tmp, ioe);
ioe = tmp;
}
throw ioe;
}

// Create a ClassVisitor to visit the methods
ClassVisitor visitor = new ClassVisitor(Opcodes.ASM9) {

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
classAccess.setValue(access);
if (superName != null) {
try {
// add(members, _getFunctionMembers(clid,
Expand All @@ -436,6 +584,18 @@ public void visit(int version, int access, String name, String signature, String
if (log != null) log.error("dynamic", e);
}
}
if (interfaces != null && interfaces.length > 0) {
for (String interf: interfaces) {
try {
// add(members, _getFunctionMembers(clid,
// cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log));
_getFunctionMembers(members, clid, cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log);
}
catch (Exception e) {
if (log != null) log.error("dynamic", e);
}
}
}
// print.e("-- " + name);
// print.e(members);

Expand Down Expand Up @@ -501,7 +661,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
};
// Start visiting the class
classReader.accept(visitor, 0);
membersCollection.put(key, cloneIt(members));
membersCollectionOld.put(key, cloneIt(members));
return members;
}

Expand All @@ -513,7 +673,8 @@ private static Map<String, FunctionMember> cloneIt(Map<String, FunctionMember> m
return cloned;
}

private static Map<String, Map<String, FunctionMember>> membersCollection = new ConcurrentHashMap<>();
private static Map<String, Map<String, FunctionMember>> membersCollectionOld = new ConcurrentHashMap<>();
private static Map<Class, Map<String, FunctionMember>> membersCollection = new IdentityHashMap<>();

public static void serialize(Serializable o, OutputStream os) throws IOException {
ObjectOutputStream oos = null;
Expand Down
2 changes: 1 addition & 1 deletion loader/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<project default="core" basedir="." name="Lucee"
xmlns:resolver="antlib:org.apache.maven.resolver.ant">

<property name="version" value="6.2.0.199-SNAPSHOT"/>
<property name="version" value="6.2.0.200-SNAPSHOT"/>

<taskdef uri="antlib:org.apache.maven.resolver.ant" resource="org/apache/maven/resolver/ant/antlib.xml">
<classpath>
Expand Down
2 changes: 1 addition & 1 deletion loader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.lucee</groupId>
<artifactId>lucee</artifactId>
<version>6.2.0.199-SNAPSHOT</version>
<version>6.2.0.200-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Lucee Loader Build</name>
Expand Down

0 comments on commit 5dca99c

Please sign in to comment.