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

update embered javasssist source code to support dynamic constant #622

Open
binfeiruci opened this issue Jan 10, 2025 · 2 comments
Open
Labels

Comments

@binfeiruci
Copy link

binfeiruci commented Jan 10, 2025

I got the error below which is fixed in Add support for the new Dynamic constant (17) created in java 11, so we need to update the emberer javaassist code.

exception stack

HOTSWAP AGENT: 11:33:00.638 ERROR (org.hotswap.agent.annotation.handler.PluginClassFileTransformer) - Unable create CtClass for 'org/springframework/beans/factory/support/DefaultListableBeanFactory'.
java.io.IOException: invalid constant type: 17 at 1746
        at org.hotswap.agent.javassist.bytecode.ConstPool.readOne(ConstPool.java:1355)
        at org.hotswap.agent.javassist.bytecode.ConstPool.read(ConstPool.java:1279)
        at org.hotswap.agent.javassist.bytecode.ConstPool.<init>(ConstPool.java:198)
        at org.hotswap.agent.javassist.bytecode.ClassFile.read(ClassFile.java:853)
        at org.hotswap.agent.javassist.bytecode.ClassFile.<init>(ClassFile.java:244)
        at org.hotswap.agent.javassist.CtClassType.<init>(CtClassType.java:98)
        at org.hotswap.agent.javassist.ClassPool.makeClass(ClassPool.java:699)
        at org.hotswap.agent.javassist.ClassPool.makeClass(ClassPool.java:677)
        at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.createCtClass(PluginClassFileTransformer.java:135)
        at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:203)
        at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:112)
        at org.hotswap.agent.util.HotswapTransformer.transform(HotswapTransformer.java:264)
        at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244)
        at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:541)
        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:150)

env

JDK17 JetBrainsRuntime

$ java -version
openjdk version "17.0.12" 2024-07-16
OpenJDK Runtime Environment JBR-17.0.12+1-1207.37-jcef (build 17.0.12+1-b1207.37)
OpenJDK 64-Bit Server VM JBR-17.0.12+1-1207.37-jcef (build 17.0.12+1-b1207.37, mixed mode)

HotswapAgent 2.0.1
jacoco 0.8.11 (as javaagent)
Springframework 6.1.6

decompile output

Decompile the class with CFR, you can see some code lines related to jacoco is using dynamic constant.

         ...
         /*
          * Uses jvm11+ dynamic constants - pseudocode provided - see https://www.benf.org/other/cfr/dynamic-constants.html
          */
         public class DefaultListableBeanFactory
         extends AbstractAutowireCapableBeanFactory
         implements ConfigurableListableBeanFactory,
         BeanDefinitionRegistry,
         Serializable {
             @Nullable
             private static Class<?> javaxInjectProviderClass;
             private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories;
             @Nullable
             private String serializationId;
             private boolean allowBeanDefinitionOverriding;
             private boolean allowEagerClassLoading;
             @Nullable
             private Comparator<Object> dependencyComparator;
             private AutowireCandidateResolver autowireCandidateResolver;
             private final Map<Class<?>, Object> resolvableDependencies;
             private final Map<String, BeanDefinition> beanDefinitionMap;
             private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders;
             private final Map<Class<?>, String[]> allBeanNamesByType;
             private final Map<Class<?>, String[]> singletonBeanNamesByType;
             private volatile List<String> beanDefinitionNames;
             private volatile Set<String> manualSingletonNames;
             @Nullable
             private volatile String[] frozenBeanDefinitionNames;
             private volatile boolean configurationFrozen;
         
             public DefaultListableBeanFactory() {
                 boolean[] blArray =  /* dynamic constant */ (boolean[])DefaultListableBeanFactory.$jacocoInit("$jacocoData", MethodHandles.lookup(), "$jacocoInit", DefaultListableBeanFactory.class);
/* 149*/         this.allowBeanDefinitionOverriding = true;
/* 152*/         this.allowEagerClassLoading = true;
/* 159*/         this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
                 blArray[0] = true;
/* 162*/         this.resolvableDependencies = new ConcurrentHashMap(16);
                 blArray[1] = true;
/* 165*/         this.beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
                 blArray[2] = true;
/* 168*/         this.mergedBeanDefinitionHolders = new ConcurrentHashMap<String, BeanDefinitionHolder>(256);
                 blArray[3] = true;
/* 171*/         this.allBeanNamesByType = new ConcurrentHashMap(64);
                 blArray[4] = true;
/* 174*/         this.singletonBeanNamesByType = new ConcurrentHashMap(64);
                 blArray[5] = true;
/* 177*/         this.beanDefinitionNames = new ArrayList<String>(256);
                 blArray[6] = true;
/* 180*/         this.manualSingletonNames = new LinkedHashSet<String>(16);
/* 195*/         blArray[7] = true;
             }
         
             public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
                 boolean[] blArray =  /* dynamic constant */ (boolean[])DefaultListableBeanFactory.$jacocoInit("$jacocoData", MethodHandles.lookup(), "$jacocoInit", DefaultListableBeanFactory.class);
/* 202*/         super(parentBeanFactory);
/* 149*/         this.allowBeanDefinitionOverriding = true;
/* 152*/         this.allowEagerClassLoading = true;
/* 159*/         this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
                 blArray[8] = true;
/* 162*/         this.resolvableDependencies = new ConcurrentHashMap(16);
                 blArray[9] = true;
/* 165*/         this.beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
                 blArray[10] = true;
/* 168*/         this.mergedBeanDefinitionHolders = new ConcurrentHashMap<String, BeanDefinitionHolder>(256);
                 blArray[11] = true;
/* 171*/         this.allBeanNamesByType = new ConcurrentHashMap(64);
                 blArray[12] = true;
/* 174*/         this.singletonBeanNamesByType = new ConcurrentHashMap(64);
                 blArray[13] = true;
/* 177*/         this.beanDefinitionNames = new ArrayList<String>(256);
                 blArray[14] = true;
/* 180*/         this.manualSingletonNames = new LinkedHashSet<String>(16);
/* 203*/         blArray[15] = true;
             }
             ...
@skybber
Copy link
Contributor

skybber commented Jan 10, 2025

Could you please create example reproducing this problem, or if you know how to fix it, prepare a pull request?

@binfeiruci
Copy link
Author

example on macos aarch64:

  1. create a demo project on start.spring.io, don't need add any dependency.
  2. download jbr_jcef-17.0.12-osx-aarch64-b1207.37.pkg(more version here) and install it.
  3. download HotswapAgent 2.0.1 and copy the jar to /Library/Java/JavaVirtualMachines/jbr_jcef-17.0.12-osx-aarch64-b1207.37/Contents/Home/lib/hotswap/hotswap-agent.jar
  4. download jacoco 0.8.11
  5. build the demo project.
  6. run /Library/Java/JavaVirtualMachines/jbr_jcef-17.0.12-osx-aarch64-b1207.37/Contents/Home/bin/java -javaagent:jacoco-0.8.11/lib/jacocoagent.jar=output=tcpserver,address=0.0.0.0,port=6300 -XX:HotswapAgent=fatjar -XX:+AllowEnhancedClassRedefinition -jar Downloads/demo/build/libs/demo-0.0.1-SNAPSHOT.jar and you will see the errors.

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

No branches or pull requests

2 participants