Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoSuchMethodException is thrown by ReflectiveInterceptor.jlClassGetDeclaredConstructor which changes jdk code behavior #234

Open
mingxhu opened this issue Aug 23, 2022 · 0 comments

Comments

@mingxhu
Copy link

mingxhu commented Aug 23, 2022

-- Test Case --
[oracle@c7 ~]$ wget https://github.com/spring-projects/spring-loaded/archive/refs/heads/master.zip
[oracle@c7 ~]$ unzip -qo master.zip
[oracle@c7 ~]$ cd spring-loaded-master/
[oracle@c7 spring-loaded-master]$ ./gradlew build -x test

You may see error, hang @
<===----------> 30% EXECUTING [33s]

:testdata-aspectj:aspectJ > Resolve dependencies of :testdata-aspectj:tools > aspectjtools-1.8.0.M1.pom

Ctrl + C
[oracle@c7 spring-loaded-master]$ grep -ir 1.8.0.M1 .
./testdata-aspectj/build.gradle:def aspectjVersion = "1.8.0.M1"

change it to 1.8.0, since milestone repository can't be accessed!

Run again,
[oracle@c7 spring-loaded-master]$ ./gradlew build -x test
[oracle@c7 spring-loaded-master]$ find . -name 'springloaded*.jar'
./springloaded/build/libs/springloaded-1.3.0.BUILD-SNAPSHOT-sources.jar
./springloaded/build/libs/springloaded-1.3.0.BUILD-SNAPSHOT.jar
./springloaded/build/libs/springloaded-1.3.0.BUILD-SNAPSHOT-javadoc.jar

[oracle@c7 spring-loaded-master]$ pwd
/home/oracle/spring-loaded-master

Create one WLS 14.1.1 domain with Oracle Jdk 1.8.0+,
JAVA_OPTS="${JAVA_OPTS} -javaagent:/home/oracle/spring-loaded-master/springloaded/build/libs/springloaded-1.3.0.BUILD-SNAPSHOT.jar -noverify"

WLS gives (tested @12.2.1.4 / 14.1.1.0)

java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at java.io.ObjectStreamClass.__sljlcgdc(ObjectStreamClass.java)
        at java.io.ObjectStreamClass.getExternalizableConstructor(ObjectStreamClass.java:1517)
        at java.io.ObjectStreamClass.access$1400(ObjectStreamClass.java:79)
        at java.io.ObjectStreamClass$3.run(ObjectStreamClass.java:517)
        at java.io.ObjectStreamClass$3.run(ObjectStreamClass.java:494)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:494)
        at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:391)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1134)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
        at weblogic.messaging.dispatcher.DispatcherWrapper.writeExternal(DispatcherWrapper.java:208)
        at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1459)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1430)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
...
Caused by: java.lang.NoSuchMethodException: weblogic.rmi.internal.CollocatedRemoteRef.<init>()
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.getDeclaredConstructor(Class.java:2178)
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlClassGetDeclaredConstructor(ReflectiveInterceptor.java:477)
        ... 76 more

-- Summary --
class weblogic.rmi.internal.CollocatedRemoteRef. class has no default constructor, when de-serialization happens:

Agent change code behavior

  • jdk code java.io.ObjectStreamClass.getExternalizableConstructor ignored NoSuchMethodException
  • but org.springsource.loaded.ri.ReflectiveInterceptor.jlClassGetDeclaredConstructor throws it out

java.io.ObjectStreamClass.getExternalizableConstructor(ObjectStreamClass.java:1517)
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/io/ObjectStreamClass.java

1422    /**
1423     * Returns public no-arg constructor of given class, or null if none found.
1424     * Access checks are disabled on the returned constructor (if any), since
1425     * the defining class may still be non-public.
1426     */
1427    private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
1428        try {
1429            Constructor<?> cons = cl.getDeclaredConstructor((Class<?>[]) null);
1430            cons.setAccessible(true);
1431            return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
1432                cons : null;
1433        } catch (NoSuchMethodException ex) {
1434            return null;
1435        }
1436    }

Clearly, @line 1433 (not same jdk version, line # is different) get catched & ignored. But java.io.ObjectStreamClass get instrumented by default (And Yes, commenting out line 100~101 will supress this error, https://github.com/spring-projects/spring-loaded/blob/master/springloaded/src/main/java/org/springsource/loaded/agent/SpringLoadedPreProcessor.java

 98 // Related to serialization
 99 // TODO [serialization] Caches in ObjectStreamClass for descriptors, need clearing on reload
100 systemClassesContainingReflection.add("java/io/ObjectStreamClass");
101 systemClassesContainingReflection.add("java/io/ObjectStreamClass$EntryFuture");

The code path changes to

java.lang.Exception: @@@ by dev, clazz = weblogic.rmi.internal.CollocatedRemoteRef
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlClassGetDeclaredConstructor(ReflectiveInterceptor.java:475)
        at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at java.io.ObjectStreamClass.__sljlcgdc(ObjectStreamClass.java)
        at java.io.ObjectStreamClass.getExternalizableConstructor(ObjectStreamClass.java:1517)

ReflectiveInterceptor.jlClassGetDeclaredConstructor throws java.lang.NoSuchMethodException out,
https://github.com/spring-projects/spring-loaded/blob/master/springloaded/src/main/java/org/springsource/loaded/ri/ReflectiveInterceptor.java

471 public static Constructor<?> jlClassGetDeclaredConstructor(Class<?> clazz, Class<?>... params)
472       throws SecurityException,
473       NoSuchMethodException {**
474     ReloadableType rtype = getRType(clazz);
475     if (rtype == null) {
476       // Non reloadable type
477       Constructor<?> c = clazz.getDeclaredConstructor(params);  << Here !**
478       return c;
479     } 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant