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

Cause net.bytebuddy.pool.TypePool$Resolution$NoSuchTypeException unexpectedly #8276

Closed
xiangtianyu opened this issue Apr 12, 2023 · 2 comments · Fixed by #8393
Closed

Cause net.bytebuddy.pool.TypePool$Resolution$NoSuchTypeException unexpectedly #8276

xiangtianyu opened this issue Apr 12, 2023 · 2 comments · Fixed by #8393
Labels
bug Something isn't working

Comments

@xiangtianyu
Copy link
Contributor

Describe the bug
When i try to run my application, it output exception "net.bytebuddy.pool.TypePool$Resolution$NoSuchTypeException: Cannot resolve type description for io.undertow.Undertow$Builder"

Steps to reproduce

  1. add allow class to AdditionalLibraryIgnoredTypesConfigurer
        .allowClass("org.springframework.boot.web.embedded.tomcat.TomcatWebServer")
        .allowClass("org.springframework.boot.web.embedded.jetty.JettyWebServer")
        .allowClass("org.springframework.boot.web.embedded.undertow.UndertowWebServer")
  1. create a new Instrmentation to get server type(tomcat, jetty)
public class Web2Instrumentation implements TypeInstrumentation {
  @Override
  public ElementMatcher<TypeDescription> typeMatcher() {
    return implementsInterface(named("org.springframework.boot.web.server.WebServer"));
  }

  @Override
  public void transform(TypeTransformer transformer) {
    transformer.applyAdviceToMethod(
        isMethod()
            .and(named("start")),
        Web2Instrumentation.class.getName() + "$WebStartAdvice");
  }

  public static class WebStartAdvice {
    @Advice.OnMethodEnter(suppress = Throwable.class)
    public static void onEnter(
        @Advice.This Object webServer
    ) {
      String className = webServer.getClass().getName();

      switch (className) {
        case "org.springframework.boot.web.embedded.tomcat.TomcatWebServer":
          System.out.println("tomcat");
          break;
        case "org.springframework.boot.web.embedded.jetty.JettyWebServer":
          System.out.println("jetty");
          break;
        case "org.springframework.boot.web.embedded.undertow.UndertowWebServer":
          System.out.println("undertow");
          break;
        case "org.springframework.boot.web.embedded.undertow.UndertowServletWebServer":
          System.out.println("undertow-servlet");
          break;
        case "org.springframework.boot.web.embedded.netty.NettyWebServer":
          System.out.println("netty");
          break;
        default:
          System.out.println("other");
          break;
      }
    }
  }
}
  1. input these dependency to application
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

and it will reproduce

But if you remove the spring-boot-starter-actuator or change the server type to undertow, it will work all right and not output error log

What did you expect to see?
No exception output

What did you see instead?

[otel.javaagent 2023-04-12 12:13:22:852 +0800] [main] DEBUG io.opentelemetry.javaagent.tooling.AgentInstaller$TransformLoggingListener - Transformed org.apache.kafka.clients.producer.KafkaProducer -- jdk.internal.loader.ClassLoaders$AppClassLoader@5c8da962
[otel.javaagent 2023-04-12 12:13:23:452 +0800] [RMI TCP Connection(1)-172.18.40.111] DEBUG io.opentelemetry.javaagent.tooling.AgentInstaller$TransformLoggingListener - Failed to handle org.springframework.boot.web.embedded.undertow.UndertowWebServer for transformation on classloader jdk.internal.loader.ClassLoaders$AppClassLoader@5c8da962
net.bytebuddy.pool.TypePool$Resolution$NoSuchTypeException: Cannot resolve type description for io.undertow.Undertow$Builder
	at net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:167)
	at net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$TokenizedGenericType.toErasure(TypePool.java:6877)
	at net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw$RawAnnotatedType.of(TypePool.java:3757)
	at net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw.resolveFieldType(TypePool.java:3655)
	at net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$LazyFieldDescription.getType(TypePool.java:7211)
	at net.bytebuddy.description.field.FieldDescription$AbstractBase.getDescriptor(FieldDescription.java:138)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining$WithFullProcessing$RedefinitionClassVisitor.<init>(TypeWriter.java:4856)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining$WithFullProcessing.writeTo(TypeWriter.java:4122)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3951)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2213)
	at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:224)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:11893)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:11828)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1700(AgentBuilder.java:11545)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12308)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12240)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doPrivileged(AgentBuilder.java)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:11771)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.transform(Unknown Source)
	at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
	at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:398)
	at io.opentelemetry.javaagent.tooling.DefineClassHandler.beforeDefineClass(DefineClassHandler.java:40)
	at io.opentelemetry.javaagent.bootstrap.DefineClassHelper.beforeDefineClass(DefineClassHelper.java:29)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1015)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletHandlerMappings.initializeDispatcherServletIfPossible(DispatcherServletHandlerMappings.java:74)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletHandlerMappings.getHandlerMappings(DispatcherServletHandlerMappings.java:63)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.describeMappings(DispatcherServletsMappingDescriptionProvider.java:105)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.lambda$describeMappings$0(DispatcherServletsMappingDescriptionProvider.java:84)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.describeMappings(DispatcherServletsMappingDescriptionProvider.java:83)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.describeMappings(DispatcherServletsMappingDescriptionProvider.java:76)
	at org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.describeMappings(DispatcherServletsMappingDescriptionProvider.java:54)
	at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.lambda$mappingsForContext$0(MappingsEndpoint.java:59)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.mappingsForContext(MappingsEndpoint.java:58)
	at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.mappings(MappingsEndpoint.java:50)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
	at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:77)
	at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60)
	at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:121)
	at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:96)
	at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:809)
	at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
	at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
	at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
	at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)
	at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:827)
	at java.base/jdk.internal.reflect.GeneratedMethodAccessor82.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
2023-04-12 12:13:23.464  INFO 40006 --- [)-172.18.40.111] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-04-12 12:13:23.465  INFO 40006 --- [)-172.18.40.111] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-04-12 12:13:23.492  INFO 40006 --- [)-172.18.40.111] o.s.web.servlet.DispatcherServlet        : Completed initialization in 26 ms

What version are you using?
1.15.0

Environment
Compiler: corretto jdk 11
OS: macos m1
Runtime (if different from JDK above): corretto jdk 11
OS (if different from OS compiled on): macos m1

@xiangtianyu xiangtianyu added the bug Something isn't working label Apr 12, 2023
@mateuszrzeszutek
Copy link
Member

That is nothing to worry about. It happens because the application loads UndertowServletWebServer here: https://github.com/spring-projects/spring-boot/blob/cbc03783d051075665601c5c6d24f60e7209905e/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletHandlerMappings.java#L73

And internally the agent is unable to fully describe this class, because it cannot resolve io.undertow.Undertow$Builder -- correctly, cause undertow is missing on the classpath.

@laurit
Copy link
Contributor

laurit commented Apr 28, 2023

With our current setup byte buddy fails transforming classes that have fields with missing types. We used to have similar problem transforming classes with methods with missing parameter or return type that was worked around with https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/SafeTypeStrategy.java where we filter out methods that would cause the transformation to fail. I think I have found a way to disable this validation, I'll submit a pr shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants