int128 / gradle-ssh-plugin

Gradle SSH Plugin
https://gradle-ssh-plugin.github.io
Apache License 2.0
319 stars 60 forks source link

Gradle system property synchronization issue #335

Open CSAllisonPrecisely opened 5 years ago

CSAllisonPrecisely commented 5 years ago

Environment info

plugin: org.hidetake:gradle-ssh-plugin:2.9.0 jsch: com.jcraft:jsch:0.1.54 gradle: 4.10.2 OS: Windows

Example Stack:

Caused by: java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.JceSecurity
    at com.jcraft.jsch.jce.AES256CTR.init(AES256CTR.java:56)
    at com.jcraft.jsch.Session.checkCipher(Session.java:2497)
    at com.jcraft.jsch.Session.checkCiphers(Session.java:2474)
    at com.jcraft.jsch.Session.send_kexinit(Session.java:624)
    at com.jcraft.jsch.Session.connect(Session.java:307)
    at com.jcraft.jsch.Session.connect(Session.java:183)
    at com.jcraft.jsch.Session$connect$4.call(Unknown Source)
    at org.hidetake.groovy.ssh.connection.ConnectionManager.connectInternal(ConnectionManager.groovy:107)
    at org.hidetake.groovy.ssh.connection.ConnectionManager$_connectInternal_closure1.doCall(ConnectionManager.groovy:85)
    at org.hidetake.groovy.ssh.connection.ConnectionManager$_connectInternal_closure1.doCall(ConnectionManager.groovy)
    at org.hidetake.groovy.ssh.util.Utility.retry(Utility.groovy:52)
    at org.hidetake.groovy.ssh.util.Utility$retry.callStatic(Unknown Source)
    at org.hidetake.groovy.ssh.connection.ConnectionManager.connectInternal(ConnectionManager.groovy:83)
    at org.hidetake.groovy.ssh.connection.ConnectionManager.connectInternal(ConnectionManager.groovy)
    at org.hidetake.groovy.ssh.connection.ConnectionManager.connect(ConnectionManager.groovy:59)
    at org.hidetake.groovy.ssh.connection.ConnectionManager$connect$0.call(Unknown Source)
    at org.hidetake.groovy.ssh.session.SessionTask.wetRun(SessionTask.groovy:61)
    at org.hidetake.groovy.ssh.session.SessionTask.call(SessionTask.groovy:48)
    at java_util_concurrent_Callable$call$0.call(Unknown Source)
    at org.hidetake.groovy.ssh.core.Service.run(Service.groovy:81)
    at org.hidetake.groovy.ssh.core.Service$run$0.call(Unknown Source)
    at org.hidetake.groovy.ssh.core.Service$run$0.call(Unknown Source)

Our build makes liberal use of ssh.run and runs many tasks using the parallel flag, so most users probably won't run into this. This problem happens intermittently. I believe the root cause is that gradle swaps out system properties while doing some things (like compile). Here is a report on gradle about a similar issue and a comment indicating the issue: https://github.com/gradle/gradle/issues/8830#issuecomment-476349575

I've worked around this in our build by doing something like this before a call to ssh.run (probably only needed on the first call):

            SystemProperties.getInstance().withSystemProperties(new Factory<String>() {
                @Override
                String create() {
                    Cipher.getInstance("AES/CTR/NoPadding")
                    "success"
                }
            })

This resolves our problem by assuring that the JCE classes that look at java.home are initialized while the system properties are in good state. This uses internal gradle classes, so you'll probably need to get them to expose something public. There also may be different usage patterns that will need different resolution code.