Visitar URL original
OpenJDK 13 requires -XX:+AllowRedefinitionToAddDeleteMethods flag · Issue #33 · reactor/BlockHound · GitHub
Skip to content

OpenJDK 13 requires -XX:+AllowRedefinitionToAddDeleteMethods flag #33

Open

Description

@juergenzimmermann

OpenJDK 12.0.1 with even Kotlin 1.3.40-eap-67 works fine. However, using OpenJDK 13 build 23 I get the following exception:

Exception in thread "main" java.lang.RuntimeException: java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
        at reactor.blockhound.BlockHound$Builder.install(BlockHound.java:264)
        at reactor.blockhound.BlockHound.install(BlockHound.java:64)
        at de.hska.kunde.ApplicationKt.main(Application.kt:51)
Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
        at reactor.blockhound.BlockHound$Builder.instrument(BlockHound.java:273)
        at reactor.blockhound.BlockHound$Builder.install(BlockHound.java:261)
        ... 2 more

Activity

  1. bsideup commented on Jun 2, 2019

    @bsideup
    Contributor

    Hi @juergenzimmermann,

    I'm afraid that's due to https://bugs.openjdk.java.net/browse/JDK-8192936 and similar to #21
    In JDK 13+, they adjusted the spec & impl and no longer allow redefining native methods :(

    We will need to find an alternative way for 13+ and J9, meanwhile, they seem to plan adding a flag to keep the behaviour for a few versions:
    https://bugs.openjdk.java.net/browse/JDK-8192936?focusedCommentId=14254266&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14254266

  2. juergenzimmermann commented on Jun 2, 2019

    @juergenzimmermann
    Author

    @bsideup When I use -XX:+AllowRedefinitionToAddDeleteMethods the stacktrace goes away

  3. bsideup commented on Jun 2, 2019

    @bsideup
    Contributor

    @juergenzimmermann thanks a lot for trying it!
    I will keep this issue open as a reminder to document this flag 👍

  4. changed the title [-]UnsupportedOperationException with OpenJDK 13[/-] [+]OpenJDK 13 requires -XX:+AllowRedefinitionToAddDeleteMethods flag[/+] on Jul 19, 2019
  5. pinned this issue on Jul 19, 2019
  6. yburkouski commented on Nov 9, 2019

    @yburkouski

    Heaving quite different behavior on Oracle JDK 13 in Windows: it does not throw an error about blocking call until I add this flag

  7. sergey-morenets commented on May 10, 2020

    @sergey-morenets

    Still reproduced with JDK 14.0.1 and BlockHound 1.0.3

  8. jaschenk commented on Jul 30, 2020

    @jaschenk

    Using Blockhound 1.0.4 and JDK 14.0.2 and specify the following in surefire plugin worked:

    <plugins>
     ...
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <version>2.22.2</version>
                 <configuration>
                     <argLine>-XX:+AllowRedefinitionToAddDeleteMethods</argLine>
                 </configuration>
             </plugin>
     ...
     </plugins>
    
  9. abdullahumer commented on Nov 29, 2020

    @abdullahumer

    any way this can be added to gradle?

  10. bsideup commented on Nov 30, 2020

    @bsideup
    Contributor

    @abdullahumer sure:

        tasks.withType(Test).all {
            if (JavaVersion.current().isCompatibleWith​(JavaVersion.VERSION_13)) {
                jvmArgs += [
                        "-XX:+AllowRedefinitionToAddDeleteMethods"
                ]
            }
        }
  11. abdullahumer commented on Dec 1, 2020

    @abdullahumer

    Thanks! @bsideup

  12. 10 remaining items

  13. CodeGTDLearn commented on Feb 17, 2022

    @CodeGTDLearn

    Using Blockhound 1.0.4 and JDK 14.0.2 and specify the following in surefire plugin worked:

    <plugins>
     ...
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <version>2.22.2</version>
                 <configuration>
                     <argLine>-XX:+AllowRedefinitionToAddDeleteMethods</argLine>
                 </configuration>
             </plugin>
     ...
     </plugins>
    

    In my case Using Blockhound 1.0.6 and JDK 15.0.6, worked

  14. KrzysztofKwiatkowskiK commented on Feb 24, 2022

    @KrzysztofKwiatkowskiK

    Using blockhound 1.0.6 and JDK 16.0.2 I am still getting this error and has to use the flag...

  15. ajax-semenov-y commented on Sep 17, 2022

    @ajax-semenov-y

    Hi. As far as I understand, according to https://bugs.openjdk.org/browse/JDK-8221528.

    "This option (AllowRedefinitionToAddOrDeleteMethods) is deprecated right away. The plan is to keep it for a couple of releases to allow customers (tool vendors) to remove dependency on old behavior from their tools."

    Do you plan BlockHound work according to the new JVM TI behavior?

  16. juliojgd commented on Dec 19, 2022

    @juliojgd

    I guess that if this issue is not solved, when the option AllowRedefinitionToAddOrDeleteMethods is removed from JVM, then Blockhound is completely unusable, right?

  17. patpatpat123 commented on May 15, 2023

    @patpatpat123

    Now in 2023, almost four years after the original issue, would it be possible to have a fix without the -XX workaround please?

  18. pderop commented on May 15, 2023

    @pderop
    Contributor

    I will take a look, but I don't promise anything for the moment, because looking at the history of this issue, without the work around flag, it seems to be a very very big deal to redefine / retransform classes (add/delete private static and private final instance methods in the new class versions).
    so, I'm afraid that for the moment, we need to continue using -XX:+AllowRedefinitionToAddDeleteMethods for JDK13+
    Is there any issues if you continue using this flag for the moment ?

    thanks.

  19. divyanshsaini1805 commented on Oct 17, 2023

    @divyanshsaini1805

    i am using Java 17 and Spring 3.1.3, even after including the -XX:+AllowRedefinitionToAddDeleteMethods flag, i am still facing the error. Is the flag removed from JVM or has the fix stopped working?

  20. pderop commented on Oct 19, 2023

    @pderop
    Contributor

    Hi @divyanshsaini1805 ,

    please open a separate issue with a reproducer project;
    From my side, I did the following which worked for me using Spring 3.1.3, and java 17:

    build.gradle:

    plugins {
        id 'java'
        id 'org.springframework.boot' version '3.1.3'
        id 'io.spring.dependency-management' version '1.1.3'
    }
    
    apply plugin: 'application'
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    
    java {
        sourceCompatibility = '17'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter'
        implementation 'io.projectreactor.netty:reactor-netty-core:1.0.37'
        implementation 'io.projectreactor.netty:reactor-netty-http:1.0.37'
        implementation('io.projectreactor.tools:blockhound:1.0.8.RELEASE')
        implementation 'javax.annotation:javax.annotation-api:1.3.2'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    tasks.named('test') {
        useJUnitPlatform()
    }
    
    task(echoServer, dependsOn: 'classes', type: JavaExec) {
        main = 'com.example.EchoServer'
        classpath = sourceSets.main.runtimeClasspath
        args ''
        systemProperty "io.netty.leakDetectionLevel", "DISABLED"
        debugOptions {
            enabled = false
            port = 5005
            server = true
            suspend = true
        }
    }
    
    

    DemoApplication.java:

    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DemoApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    }
    

    Demo.java:

    package com.example.demo;
    
    import org.springframework.stereotype.Component;
    import reactor.blockhound.BlockHound;
    import reactor.netty.tcp.TcpServer;
    
    import javax.annotation.PostConstruct;
    
    @Component
    public class Demo {
        static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));
    
        @PostConstruct
        public void init() {
            System.out.println("Jdk version used: " + System.getProperty("java.version"));
            BlockHound.install();
    
            TcpServer server =
                    TcpServer.create()
                            .port(PORT)
                            .handle((in, out) -> {
                                try {
                                    Thread.sleep(100);
                                } catch (Throwable err) {
                                    err.printStackTrace();
                                }
                                return out.send(in.receive().retain());
                            });
    
            server.bindNow()
                    .onDispose()
                    .block();
        }
    }
    
    

    then, from one console using java17:

    ./gradlew build
    java -XX:+AllowRedefinitionToAddDeleteMethods -jar build/libs/demo-0.0.1-SNAPSHOT.jar
    

    from another console:

    curl -v http://localhost:8080/foo
    

    this will display the following from the first console:

    reactor.blockhound.BlockingOperationError: Blocking call! java.lang.Thread.sleep
    	at java.base/java.lang.Thread.sleep(Thread.java)
    	at com.example.demo.Demo.lambda$init$0(Demo.java:34)
    	at reactor.netty.tcp.TcpServer$OnConnectionHandle.accept(TcpServer.java:277)
    	at reactor.netty.tcp.TcpServer$OnConnectionHandle.accept(TcpServer.java:264)
    	at reactor.netty.transport.ServerTransportConfig$ServerTransportDoOnConnection.onStateChange(ServerTransportConfig.java:253)
    	at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:481)
    	at reactor.netty.channel.ChannelOperationsHandler.channelActive(ChannelOperationsHandler.java:62)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:262)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:238)
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:231)
    	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelActive(DefaultChannelPipeline.java:1398)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:258)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:238)
    	at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:895)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:522)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486)
    	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    	at java.base/java.lang.Thread.run(Thread.java:833)
    

    Thanks.

  21. apferrarone commented on Jan 12, 2024

    @apferrarone

    I have tried on windows with corretto-17 and temurin-17. When I add the vm option to the Surefire plugin config in pom.xml, my unit tests work with BlockHound. But when I add the vm option to my IntelliJ run configuration or in the vm options file I still see this error when I start up my springboot app:

    OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
    Exception in thread "main" java.lang.ExceptionInInitializerError
    Caused by: java.lang.IllegalStateException: The instrumentation have failed.
    It looks like you're running on JDK 13+.
    You need to add '-XX:+AllowRedefinitionToAddDeleteMethods' JVM flag.
    
    public static void main(String[] args) {
    	System.out.println(args[0] + " ");
    	SpringApplication.run(BillGenerationServiceApplication.class, args);
    }
    

    I see this: -XX:+AllowRedefinitionToAddDeleteMethods at the top of the console.

    Any ideas? Thanks.

  22. divyanshsaini1805 commented on Jan 16, 2024

    @divyanshsaini1805

    Hi @divyanshsaini1805 ,

    please open a separate issue with a reproducer project; From my side, I did the following which worked for me using Spring 3.1.3, and java 17:

    build.gradle:

    plugins {
        id 'java'
        id 'org.springframework.boot' version '3.1.3'
        id 'io.spring.dependency-management' version '1.1.3'
    }
    
    apply plugin: 'application'
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    
    java {
        sourceCompatibility = '17'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter'
        implementation 'io.projectreactor.netty:reactor-netty-core:1.0.37'
        implementation 'io.projectreactor.netty:reactor-netty-http:1.0.37'
        implementation('io.projectreactor.tools:blockhound:1.0.8.RELEASE')
        implementation 'javax.annotation:javax.annotation-api:1.3.2'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    tasks.named('test') {
        useJUnitPlatform()
    }
    
    task(echoServer, dependsOn: 'classes', type: JavaExec) {
        main = 'com.example.EchoServer'
        classpath = sourceSets.main.runtimeClasspath
        args ''
        systemProperty "io.netty.leakDetectionLevel", "DISABLED"
        debugOptions {
            enabled = false
            port = 5005
            server = true
            suspend = true
        }
    }
    

    DemoApplication.java:

    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DemoApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    }
    

    Demo.java:

    package com.example.demo;
    
    import org.springframework.stereotype.Component;
    import reactor.blockhound.BlockHound;
    import reactor.netty.tcp.TcpServer;
    
    import javax.annotation.PostConstruct;
    
    @Component
    public class Demo {
        static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));
    
        @PostConstruct
        public void init() {
            System.out.println("Jdk version used: " + System.getProperty("java.version"));
            BlockHound.install();
    
            TcpServer server =
                    TcpServer.create()
                            .port(PORT)
                            .handle((in, out) -> {
                                try {
                                    Thread.sleep(100);
                                } catch (Throwable err) {
                                    err.printStackTrace();
                                }
                                return out.send(in.receive().retain());
                            });
    
            server.bindNow()
                    .onDispose()
                    .block();
        }
    }
    

    then, from one console using java17:

    ./gradlew build
    java -XX:+AllowRedefinitionToAddDeleteMethods -jar build/libs/demo-0.0.1-SNAPSHOT.jar
    

    from another console:

    curl -v http://localhost:8080/foo
    

    this will display the following from the first console:

    reactor.blockhound.BlockingOperationError: Blocking call! java.lang.Thread.sleep
    	at java.base/java.lang.Thread.sleep(Thread.java)
    	at com.example.demo.Demo.lambda$init$0(Demo.java:34)
    	at reactor.netty.tcp.TcpServer$OnConnectionHandle.accept(TcpServer.java:277)
    	at reactor.netty.tcp.TcpServer$OnConnectionHandle.accept(TcpServer.java:264)
    	at reactor.netty.transport.ServerTransportConfig$ServerTransportDoOnConnection.onStateChange(ServerTransportConfig.java:253)
    	at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:481)
    	at reactor.netty.channel.ChannelOperationsHandler.channelActive(ChannelOperationsHandler.java:62)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:262)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:238)
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:231)
    	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelActive(DefaultChannelPipeline.java:1398)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:258)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:238)
    	at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:895)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:522)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486)
    	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    	at java.base/java.lang.Thread.run(Thread.java:833)
    

    Thanks.

    hi, i know it's been a super long time, but since this thread is a lot active, i would like to add my part,
    for Spring 3.1.3, and java 17,
    the -XX:+AllowRedefinitionToAddDeleteMethods flag works good indeed if used with the following command:
    java -XX:+AllowRedefinitionToAddDeleteMethods -jar target/Required_jar_file.jar,

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions