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

[Question] AgentBuilder.InitializationStrategy.SelfInjection's behaviour in detail #1608

Open
cgs041328 opened this issue Mar 22, 2024 · 2 comments
Assignees
Milestone

Comments

@cgs041328
Copy link

cgs041328 commented Mar 22, 2024

Background

I wrote a ThreadSubclassInterceptor to transform Thread's Subclass.

class ThreadSubclassInterceptor {
    public AgentBuilder install(AgentBuilder agentBuilder) {
        return agentBuilder
                .type(hasSuperType(named("java.lang.Thread"))
                        .and(not(named("java.lang.Thread").or(nameStartsWith("java.lang.ref")))))
                .transform((builder, typeDescription, classLoader, module) -> {
                    ...
                    return builder;
                });
    }

I ran the JDK test and exception thrown.

java.lang.ExceptionInInitializerError
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:467)
    at Security.setupProxy(Security.java:172)
    at Security.main(Security.java:447)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
    at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:485)
    at java.base/java.security.AccessController.checkPermission(AccessController.java:1068)
    at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:416)
    at java.base/java.lang.ClassLoader.checkClassLoaderPermission(ClassLoader.java:2060)
    at java.base/java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1948)
    at ProxyServer.<clinit>(ProxyServer.java:56)
    ... 11 more

I found that it's because ProxyServer extends thread class so it will be instrumented, and because of AgentBuilder's default strategy, code below will be added.

    static {
  ClassLoader.getSystemClassLoader().loadClass("net.bytebuddy.dynamic.Nexus").getMethod("initialize", Class.class, Integer.TYPE).invoke((Object)null, ProxyServer.class, -429884501);
        ...
    }

While in the policy of the test, there is no getClassLoader permission, so the exception will be thrown.

I tried to change the strategy to InitializationStrategy.NoOp and it worked but still not sure if it's safe to do so.

Question

May i know In which case it's safe to change the InitializationStrategy to NoOp or Minimal? I tried to understand InitializationStrategy.SelfInjection's behaviour by reading the source code, looks like what it's trying to do is to call the LoadedTypeInitializer registered in the instrumented type and it's auxiliary types, but it's still not very clear to me what does those LoadedTypeInitializers do, can i get some explanation is detail or some examples? Thank you so much.

@raphw
Copy link
Owner

raphw commented Mar 25, 2024

If any of your instrumentations requires dispatch to an object, it is required. But normally it is not. I will see if I can change it to detect this automatically. But unless you do something like MethodDelegation.to(new MyDispatcher()), it should be safe.

@raphw raphw self-assigned this Mar 25, 2024
@raphw raphw added this to the 1.14.13 milestone Mar 25, 2024
@cgs041328
Copy link
Author

Thank you for your explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants