Is it possible to run Jenkins created by JenkinsRule in a separate JVM?

92 views
Skip to first unread message

Kirill

unread,
Apr 29, 2017, 5:36:43 AM4/29/17
to Jenkins Developers
Hi,

I wrote a unit test (following guidelines at https://wiki.jenkins-ci.org/display/JENKINS/Unit+Test) to test different usage scenarios of the Swarm 3.4 slaves.
So I used:
- Jenkins test harness 2.21 (the latest one)
- Jenkins core 2.25
- Swarm client v3.4

I wrote the test using @WithPlugin("swarm-3.4.hpi"), which brings up the Swarm slave targeted at jenkins/getrootUrl(), but I get the following error during Jenkins startup:

INFO: Listed all plugins
Apr 29, 2017 10:30:32 AM hudson.ExtensionFinder$Sezpoz scout
WARNING: Failed to scout jenkins.slaves.DefaultJnlpSlaveReceiver
java.lang.NoClassDefFoundError: org/jenkinsci/remoting/engine/JnlpServerHandshake

It appeared that Jenkins 2.25 uses Jenkins remoting v2.62, but Swarm client v3.4 which I use to create slave in my test uses Jenkins remoting v3.4.1, which doesn't have that class. As the Swarm client's library is loaded before Jenkins (and it does, as it's one of the Maven module's dependencies, so gets onto classpath right away), embedded Jenkins started by JenkinsRule gets it as well, neglecting the remoting.jar in its WEB-INF.

If Jenkins would have been started in a JVM separate from the test's JVM, there wouldn't be such problem. Of course, it wouldn't be a unit test then, but the embedded Jenkins is still better to me than a standalone instance.
Maybe another idea would be to use Jenkins acceptance test harness?

Any ideas are welcome! Thanks in advance, folks.

Stephen Connolly

unread,
Apr 29, 2017, 7:39:10 AM4/29/17
to jenkin...@googlegroups.com
There are surefire options to let you filter the test classpath


--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/69f79be6-f504-43b4-8088-66a3172b1127%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Sent from my phone

Kirill Shepitko

unread,
May 2, 2017, 4:26:08 AM5/2/17
to jenkin...@googlegroups.com
Thanks for suggestion, Stephen!

I added to my POM:

<pluginManagement>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <classpathDependencyExcludes>
                    <classpathDependencyExclude>org.jenkins-ci.main:remoting</classpathDependencyExclude>
                </classpathDependencyExcludes>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

However, this didn't have any effect.
I think that the reason is that swarm-client is an uber-jar created via shade plugin, so all remoting stuff is packed there. Also, if I override version of org.jenkins-ci.main:remoting to 2.62 (the one used in Jenkins core), Jenkins starts fine, but Swarm client connection to it fails with this:

SEVERE: A thread (Thread-25/80) died unexpectedly due to an uncaught exception, this may leave your Jenkins in a bad way and is usually indicative of a bug in the code.
java.lang.SecurityException: class "org.jenkinsci.remoting.engine.JnlpProtocolHandlerFactory"'s signer information does not match signer information of other classes in the same package
............
    at hudson.remoting.Engine.innerRun(Engine.java:299)
    at hudson.remoting.Engine.run(Engine.java:287)

Which is obviously caused by the same reason - 3.x remoting is inevitably shipped with swarm-client, even if the Maven dependency itself is removed/overridden.
So Surefire settings won't help.

Does it make sense to try to use Jenkins acceptance test harness for such test?


2017-04-29 12:38 GMT+01:00 Stephen Connolly <stephen.al...@gmail.com>:
On Sat 29 Apr 2017 at 10:36, Kirill <yam...@gmail.com> wrote:
Hi,

I wrote a unit test (following guidelines at https://wiki.jenkins-ci.org/display/JENKINS/Unit+Test) to test different usage scenarios of the Swarm 3.4 slaves.
So I used:
- Jenkins test harness 2.21 (the latest one)
- Jenkins core 2.25
- Swarm client v3.4

I wrote the test using @WithPlugin("swarm-3.4.hpi"), which brings up the Swarm slave targeted at jenkins/getrootUrl(), but I get the following error during Jenkins startup:

INFO: Listed all plugins
Apr 29, 2017 10:30:32 AM hudson.ExtensionFinder$Sezpoz scout
WARNING: Failed to scout jenkins.slaves.DefaultJnlpSlaveReceiver
java.lang.NoClassDefFoundError: org/jenkinsci/remoting/engine/JnlpServerHandshake

It appeared that Jenkins 2.25 uses Jenkins remoting v2.62, but Swarm client v3.4 which I use to create slave in my test uses Jenkins remoting v3.4.1, which doesn't have that class. As the Swarm client's library is loaded before Jenkins (and it does, as it's one of the Maven module's dependencies, so gets onto classpath right away), embedded Jenkins started by JenkinsRule gets it as well, neglecting the remoting.jar in its WEB-INF.

If Jenkins would have been started in a JVM separate from the test's JVM, there wouldn't be such problem. Of course, it wouldn't be a unit test then, but the embedded Jenkins is still better to me than a standalone instance.
Maybe another idea would be to use Jenkins acceptance test harness?

Any ideas are welcome! Thanks in advance, folks.

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-dev+unsubscribe@googlegroups.com.
--
Sent from my phone

--
You received this message because you are subscribed to a topic in the Google Groups "Jenkins Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-dev/rEk5FNjd7SU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CA%2BnPnMxdEaTbVXSTvkJHf%3DXRkbiUbxAQm5FezfC1zwJC69K0Dg%40mail.gmail.com.

Stephen Connolly

unread,
May 2, 2017, 4:38:30 AM5/2/17
to jenkin...@googlegroups.com
Ahhh you are using shade. perhaps you need to modify the use of shade due to MNG-5899

Kirill Shepitko

unread,
May 2, 2017, 4:45:58 AM5/2/17
to jenkin...@googlegroups.com

Stephen Connolly

unread,
May 2, 2017, 5:40:40 AM5/2/17
to jenkin...@googlegroups.com
So AIUI all those dependencies should be marked as "provided" scope (though there is some fun with shade getting it to shade the "provided" dependencies)

On 2 May 2017 at 09:45, Kirill Shepitko <yam...@gmail.com> wrote:
Nope, not me - the developers of Swarm plugin's client (https://github.com/jenkinsci/swarm-plugin/blob/master/client/pom.xml).

Jesse Glick

unread,
May 2, 2017, 12:32:53 PM5/2/17
to Jenkins Dev
On Sat, Apr 29, 2017 at 5:36 AM, Kirill <yam...@gmail.com> wrote:
> As the Swarm client's library is loaded
> before Jenkins (and it does, as it's one of the Maven module's dependencies,
> so gets onto classpath right away), embedded Jenkins started by JenkinsRule
> gets it as well, neglecting the remoting.jar in its WEB-INF.

Cf. JENKINS-41827. For now your only options are to create an
acceptance test (realistic but slow and flaky and hard to couple with
plugin changes), or simply request `remoting` 3.4.1 as a `test`-scoped
dependency in your POM to override whatever that version of Jenkins
shipped with.

Kirill Shepitko

unread,
May 3, 2017, 2:08:53 AM5/3/17
to jenkin...@googlegroups.com
Hi Jesse,

Thanks for pointing me to this ticket! It makes a good sense.

I tried acceptance-test-harness yesterday, but found it too flaky to be used. I managed to set it to detect Jenkins WAR from Maven, but test during Jenkins startup with some weird internal Guice errors. I tried both "extends AbstractJUnitTest" and @Rule, with the same result. And it opens the browser regardless of whether I want it or not. Looks like this harness is exactly for Jenkins builds' verification, and is flaky if used for other purposes.


"request `remoting` 3.4.1 as a `test`-scoped dependency in your POM to override whatever that version of Jenkins shipped with."
--------------
Actually that's the first option I tried in the beginning, but Jenkins 2.25 seems to be relying on some classes' existence from remoting 2.62. So if I force it to use remoting 3.4.1, it fails on startup, complaining about class missing in 3.4.1. Basically, that's the same issue when Swarm plugin client's classes get into the Jenkins's class loader - but in this case I'm pushing "bad" library forcibly.

Also, I thought that dependency manipulation is not OK when it comes to integration testing. Because in this case you're not testing what you will have in the reality (like it's stressed in https://issues.jenkins-ci.org/browse/JENKINS-41827), therefore there's no much good in this test. That's why I thought of Jenkins started in a separate JVM as a better choice. Wouldn't this be easier than co-ordinating the class loaders, like in http://hg.netbeans.org/main/file/tip/nbjunit/src/org/netbeans/junit/NbModuleSuite.java?

--
You received this message because you are subscribed to a topic in the Google Groups "Jenkins Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-dev/rEk5FNjd7SU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-dev+unsubscribe@googlegroups.com.

Jesse Glick

unread,
May 3, 2017, 7:01:24 AM5/3/17
to Jenkins Dev
ATH is the only currently supported option. The test must live in the test repository, not in your plugin repository.

Or just select a more recent baseline version of Jenkins.
Reply all
Reply to author
Forward
0 new messages