Code Monkey home page Code Monkey logo

jenkins-test-harness's Introduction

jenkins-test-harness's People

Contributors

abayer avatar abhyudayasharma avatar basil avatar batmat avatar daniel-beck avatar darxriggs avatar dependabot-preview[bot] avatar dependabot[bot] avatar dwnusbaum avatar ikedam avatar jglick avatar joseblas avatar jtnord avatar kohsuke avatar kutzi avatar markewaite avatar offa avatar olamy avatar oleg-nenashev avatar olivergondza avatar raul-arabaolaza avatar reda-alaoui avatar renovate[bot] avatar stephenc avatar svanoort avatar tfennelly avatar timja avatar uhafner avatar vlatombe avatar wadeck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jenkins-test-harness's Issues

race condition unpacking wars with multiple concurrent tests

Jenkins and plugins versions report

stack trace
java.nio.file.NoSuchFileException: /jenkins/workspace/builders_URR-pr-builder_PR-10094/work/output-command-launcher/work/command-launcher-plugin/target/jenkins-for-testx/jsbundles/vendors.js
  at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
  at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
  at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
  at java.base/sun.nio.fs.UnixFileAttributeViews$Posix.setMode(UnixFileAttributeViews.java:254)
  at java.base/sun.nio.fs.UnixFileAttributeViews$Posix.setPermissions(UnixFileAttributeViews.java:276)
  at java.base/java.nio.file.Files.setPosixFilePermissions(Files.java:2080)
  at hudson.FilePath._chmod(FilePath.java:1973)
  at hudson.FilePath$Chmod.invoke(FilePath.java:1959)
  at hudson.FilePath$Chmod.invoke(FilePath.java:1949)
  at hudson.FilePath.act(FilePath.java:1198)
  at hudson.FilePath.act(FilePath.java:1181)
  at hudson.FilePath.chmod(FilePath.java:1946)
  at hudson.FilePath.unzip(FilePath.java:738)
  at hudson.FilePath$UnzipLocal.invoke(FilePath.java:605)
  at hudson.FilePath$UnzipLocal.invoke(FilePath.java:592)
  at hudson.FilePath.act(FilePath.java:1198)
  at hudson.FilePath.act(FilePath.java:1181)
  at hudson.FilePath.unzip(FilePath.java:572)
  at org.jvnet.hudson.test.WarExploder.explode(WarExploder.java:161)
  at org.jvnet.hudson.test.WarExploder.getExplodedDir(WarExploder.java:62)
  at org.jvnet.hudson.test.JenkinsRule._createWebServer(JenkinsRule.java:797)
  at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:752)
  at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:741)
  at org.jvnet.hudson.test.JenkinsRule.newHudson(JenkinsRule.java:693)
  at org.jvnet.hudson.test.JenkinsRule.before(JenkinsRule.java:407)

What Operating System are you using (both controller, and any agents involved in the problem)?

N/A but Linux.

Reproduction steps

  • repeatedly run git clean -fdx && mvn test -DforkCount=20 in a plugin
  • eventually it will fail with a stack like that provided above (where eventually may be longer than the lifetime of the person reproducing - or it may not be - the window of opportunity is narrow and depends on many factors like IO available at the time, CPU, when the os schedules a different process.... )

Expected Results

no failure like above

Actual Results

it randomly fails

Anything else?

code inspection shows the race condition between the check of the directory and the creation of the files that are used for the check of the directory

This can result in multiple concurrent processes (surefire forks are different processes not threads) unpacking the war.

Remove dependency on Commons Lang 3

This component depends on Commons Lang 3 and delivers it via the shaded jenkins-test-harness-htmlunit in the normal package namespace. This is problematic because there exists a Commons Lang 3 library plugin, which also might be on the test classpath and might provide the identical classes, and based on the order of the dependencies on the classpath one or the other might be used. Ideally we would remove the dependency on Commons Lang 3, for example by relocating the packages in the shaded jenkins-test-harness-htmlunit JAR, but this is challenging for a few reasons:

  • This component itself exposes an ImmutablePair type in its public API (via JenkinsRule._createWebServer), so consumers would need to be adapted.
  • The fact that the test harness has delivered Commons Lang 3 on the classpath for a long time means that a few dozen plugins have grown to depend on it, so removing it would break upgrade for those plugins. They should be adapted ahead of time to drop their dependency on Commons Lang 3 (for example, by instead depending on the Commons Lang 2 provided by Jenkins core or standard Java Platform functionality).

Missing Dependency in `PluginAutomaticTestBuilder`?

Hi,

I'm not quite sure where to report this issue, but this seems like a reasonable place to start. The answer may well end up being somewhere else, however - I also faced this issue when updating plugins on my most recent Jenkins deployment. Declaring the commons-text-api as a top-level dependency worked there, which points to this being more than a test harness issue.

I've been updating some plugins from baseline Jenkins 2.375.4 to 2.387.3 and getting several failures from InjectedTest.testPluginActive that look like this:

[ERROR] InjectedTest.testPluginActive -- Time elapsed: 0.003 s <<< FAILURE!
java.lang.AssertionError: While testing build-name-setter, plugin-util-api failed to start
        at org.jvnet.hudson.test.PluginAutomaticTestBuilder$OtherTests.testPluginActive(PluginAutomaticTestBuilder.java:98)
...
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.io.IOException: Failed to load: Plugin Utilities API Plugin (plugin-util-api 3.3.0)
 - Plugin is missing: commons-text-api (1.10.0-36.vc008c8fcda_7b_)
 - Plugin is missing: commons-lang3-api (3.12.0-36.vd97de6465d5b_)

plugin-util-api is not a dependency of the project. In looking at the dependencies of recent releases of plugin-util-api, I did not see anything to suggest this dependency was just dropped either. Here are a few examples where running mvn clean verify will reproduce the problem:

In one case I fixed the test by adding a test-scoped dependency, but a more centralized fix would be better.
jenkinsci/naginator-plugin@85c11e2

How much longer for HtmlUnit?

HtmlUnit is based on the venerable Rhino JavaScript engine, which does not support the optional chaining (?.) operator, spread (...) syntax, or rest parameter syntax (among other newer ECMAScript language features). The Web platform is evolving at a fast pace, and Rhino is increasingly falling behind mainstream browsers. It takes an exceptionally committed group of developers to keep up (cf. LibJS).

The status quo is that we simply avoid using these newer ECMAScript language features in Jenkins core in order to support JTH/HtmlUnit/Rhino in core and plugin integration tests (as opposed to ATH/Selenium). Plugins that use e.g. Bootstrap 5 (which uses the newer rest parameter syntax) cannot be tested with JTH/HtmlUnit/Rhino and must instead be tested with ATH/Selenium. This seems unsustainable.

The last version of ECMAScript that is fully supported by Rhino is 5.1. We could transpile our code to ECMAScript 5.1 to avoid any problems with JTH/HtmlUnit/Rhino, but this seems like an undesirable short-term measure that would negatively impact performance in the production use case for mainstream browsers.

Another solution would be to teach Can I use/Browserslist/Babel which features are (or are not) supported by HtmlUnit/Rhino. Then we could transpile our code to something that would run in JTH/HtmlUnit/Rhino with minimal modifications. This would be a modest amount of effort and would require upstream changes, but it seems relatively achievable in the medium term.

Yet another solution would be to rewrite usages of JTH/HtmlUnit/Rhino in core and plugin integration tests in favor of a mainstream browser using ATH/Selenium (keeping them in their existing repositories or moving them to jenkinsci/acceptance-test-harness being a related but somewhat orthogonal question). Recent versions of Selenium can automatically download the Selenium drivers needed for various browsers, and our Docker images used for CI jobs already have e.g. Chrome installed. For local builds, developers could be instructed to install a browser, or we could skip those tests when a browser is not available (relying on the CI builds instead).

The most challenging aspect of the above is that there are hundreds (if not thousands) of existing core and plugin integration tests, and porting them all from JTH/HtmlUnit/Rhino to ATH/Selenium seems prohibitively impractical. Perhaps the existing JenkinsRule.WebClient interface in JTH could be rewritten in terms of Selenium rather than in terms of HtmlUnit/Rhino? This might break binary (but not source?) compatibility with JTH, making the migration easier (though still not trivial). The interface could then be deprecated in favor of native ATH equivalents, with usages in core and plugin integration tests being gradually migrated to ATH over time.

What I described in the last paragraph seems fairly challenging at first glance. I have no idea whether this is feasible or not, but I think it is worth exploring. Let me know if you are interested in contributing code to this effort.

JenkinsLocationConfiguration.xml file is not created when using startJenkins()

Jenkins and plugins versions report

Environment Only JTH

What Operating System are you using (both controller, and any agents involved in the problem)?

Mac OS

Reproduction steps

This test shows the error:

      rr.startJenkins();
      String[] jenkinsLocations = rr.getHome().list(
              (dir, name) -> name.equalsIgnoreCase("jenkins.model.JenkinsLocationConfiguration.xml"));
      assertThat(jenkinsLocations, IsArrayWithSize.arrayWithSize(1));

When using rr.runRemotely the files is created (this includes rr.then), but not always then can be used (or makes testing very complex at least).

This test currently passes

  rr.then( s -> {
        String[] jenkinsLocations = s.jenkins.getRootDir().list(
                (dir, name) -> name.equalsIgnoreCase("jenkins.model.JenkinsLocationConfiguration.xml"));
        assertThat(jenkinsLocations, IsArrayWithSize.arrayWithSize(1));
        });

And this both scenarios should have the same outcome.

In my particular case, I have two Jenkins instances connecting to each other, one provides a file where the connections details are provided, which cannot be created (using RealJenkinsRule) because the locations hasn't been set yet.

This error happens now because previously the port was assigned beforehand and now is assigned by jetty in runtime by a file. To that port number could be passed out as param in jcasc

unclassified:
 location:
   url: ${MY_URL}

but now is impossible.

Expected Results

JenkinsLocationConfiguration.xml file exists when the RealJenkinsRule is used.

Actual Results

The mentioned file doesn't exist.

Anything else?

No response

HTTPS for Update Center

Jenkins and plugins versions report

Jenkins 2.303.3

What Operating System are you using (both controller, and any agents involved in the problem)?

Any

Reproduction steps

In https://github.com/jenkinsci/jenkins-test-harness/blob/master/src/main/java/org/jvnet/hudson/test/JavaNetReverseProxy.java#L65, the update-center.json file is loaded over HTTP. In my environment in particular, we disallow HTTP access, so when the test harness is executed it is unable to load the update-center.json. This generally cascades into weird and obscure errors stating that various plugins under test are not loaded.

Expected Results

update-center.json is loaded over HTTPS.

Actual Results

Various plugin dependencies report that they are not installed.

Anything else?

No response

JUnit Jupiter Extension fails on constructor injection with multiple test methods

Jenkins and plugins versions report

Environment
mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /usr/local/Cellar/maven/3.9.6/libexec
Java version: 17.0.9, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk@17/17.0.9/libexec/openjdk.jdk/Contents/Home
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "14.2.1", arch: "x86_64", family: "mac"

What Operating System are you using (both controller, and any agents involved in the problem)?

N/A

Reproduction steps

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.collection.IsEmptyCollection.empty;

import java.io.IOException;
import java.util.Objects;

import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.JenkinsRule;

@WithJenkins
class JenkinsRuleConstructorResolverTest {

    private final JenkinsRule rule;

    JenkinsRuleConstructorResolverTest(JenkinsRule rule) {
        this.rule = Objects.requireNonNull(rule);
    }

    @Test
    void firstTest() throws IOException {
        assertThat(rule.jenkins.getJobNames(), empty());
        rule.createFreeStyleProject("job-0");
        assertThat(rule.jenkins.getJobNames(), hasSize(1));
        assertThat(rule.jenkins.getJobNames(), hasItem("job-0"));
    }

    @Test
    void secondTest() throws IOException {
        assertThat(rule.jenkins.getJobNames(), empty());
        rule.createFreeStyleProject("job-1");
        assertThat(rule.jenkins.getJobNames(), hasSize(1));
        assertThat(rule.jenkins.getJobNames(), hasItem("job-1"));
    }
}

Expected Results

Tests should execute successfully, preusumably with a "reset Jenkins" instance since the default operating mode for Jenkins test instance lifecycle is per-method (see docs and @TestInstance)

Actual Results

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleConstructorResolverTest.secondTest -- Time elapsed: 0.002 s <<< ERROR!
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to bind to localhost/127.0.0.1:58115
	at org.jvnet.hudson.test.junit.jupiter.JenkinsExtension.resolveParameter(JenkinsExtension.java:107)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.io.IOException: Failed to bind to localhost/127.0.0.1:58115
	at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:344)
	at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:304)
	at org.eclipse.jetty.server.Server.lambda$doStart$0(Server.java:402)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at org.eclipse.jetty.server.Server.doStart(Server.java:398)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
	at org.jvnet.hudson.test.JenkinsRule._createWebServer(JenkinsRule.java:885)
	at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:803)
	at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:791)
	at org.jvnet.hudson.test.JenkinsRule.newHudson(JenkinsRule.java:741)
	at org.jvnet.hudson.test.JenkinsRule.before(JenkinsRule.java:409)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsExtension.resolveParameter(JenkinsExtension.java:104)
	... 3 more
Caused by: java.net.BindException: Address already in use
	at java.base/sun.nio.ch.Net.bind0(Native Method)
	at java.base/sun.nio.ch.Net.bind(Net.java:555)
	at java.base/sun.nio.ch.ServerSocketChannelImpl.netBind(ServerSocketChannelImpl.java:337)
	at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:294)
	at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:339)
	... 23 more

Test fails to execute due to a binding exception

Anything else?

No response

Are you interested in contributing a fix?

Yes, would like to improve the JUnit 5 support in a few other ways with other issues I've found (like with @JenkinsRecipe as well)

Cleanup terminology in the Jenkins Test Harness lib

The Jenkins test Harness library still uses a lot of deprecated "slave" and "master" terminology in its APIs. It would be nice to clean it up by...

  • Editing documentation, including Markdown files and Javadoc
  • Removing old terminology in methods by deprecating them and introducing the replacement ones (example for JenkinsRule#createSlave() - #337 )
  • Creating new test classes that do not include the obsolete names
  • Cleaning up local variables and comments

All of that can be done in small atomic pull requests, contributors are welcome!

More info

Running `mvn test` in this repository on Java 18 fails with `Maven surefire tests fail with java.lang.reflect.InaccessibleObjectException`

Jenkins and plugins versions report

Environment ```text Windows 10 version 20H2

openjdk version "18.0.2.1" 2022-08-18
OpenJDK Runtime Environment (build 18.0.2.1+1-1)
OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)

Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: c:\Users...\Documents\maven
Java version: 18.0.2.1, vendor: Oracle Corporation, runtime: c:\Users...\Documents\java
Default locale: en_GB, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

</details>


### What Operating System are you using (both controller, and any agents involved in the problem)?

Windows 10 version 20H2

### Reproduction steps

1. Install OpenJDK 18, Maven 3.8.6
2. Checkout and enter jenkins-test-harness
3. Run "mvn test" 

### Expected Results

All tests passed.

### Actual Results

```text
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
Aug 24, 2022 10:35:11 AM org.eclipse.jetty.util.log.Log initialized
INFO: Logging initialized @36935ms to org.eclipse.jetty.util.log.Slf4jLog
Aug 24, 2022 10:35:12 AM jenkins.model.Jenkins <clinit>
SEVERE: Failed to load Jenkins.class
java.lang.ExceptionInInitializerError
        at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:811)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:574)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:496)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:465)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:411)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:378)
        at hudson.util.XStream2.<init>(XStream2.java:113)
        at jenkins.model.Jenkins.<clinit>(Jenkins.java:5379)
        at hudson.PluginManager.<clinit>(PluginManager.java:2113)
        at org.jvnet.hudson.test.HudsonTestCase.<init>(HudsonTestCase.java:279)
        at org.jvnet.hudson.test.HudsonTestCaseShutdownSlaveTest.<init>(HudsonTestCaseShutdownSlaveTest.java:45)
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
        at junit.framework.TestSuite.createTest(TestSuite.java:59)
        at junit.framework.TestSuite.addTestMethod(TestSuite.java:296)
        at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:139)
        at junit.framework.TestSuite.<init>(TestSuite.java:118)
        at org.junit.internal.runners.JUnit38ClassRunner.<init>(JUnit38ClassRunner.java:78)
        at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:11)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
        at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder.runnerForClass(DefensiveAllDefaultPossibilitiesBuilder.java:57)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolveTestClass(ClassSelectorResolver.java:66)
        at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:47)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
        at org.junit.vintage.engine.discovery.VintageDiscoverer.discover(VintageDiscoverer.java:42)
        at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:64)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
        at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
        at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:78)
        at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.discover(DefaultLauncherSession.java:81)
        at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:48)
        at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:56)
        at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:102)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:167)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.getSuites(JUnitPlatformProvider.java:109)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:577)
        at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:165)
        at org.apache.maven.surefire.api.util.ReflectionUtils.invokeGetter(ReflectionUtils.java:76)
        at org.apache.maven.surefire.api.util.ReflectionUtils.invokeGetter(ReflectionUtils.java:70)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.getSuites(ProviderFactory.java:145)
        at org.apache.maven.plugin.surefire.booterclient.ForkStarter.getSuitesIterator(ForkStarter.java:751)
        at org.apache.maven.plugin.surefire.booterclient.ForkStarter.runSuitesForkPerTestSet(ForkStarter.java:431)
        at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:327)
        at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:269)
        at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1334)
        at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1167)
        at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:931)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2(MojoExecutor.java:370)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:196)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @1c7d3fd5
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
        at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:180)
        at java.base/java.lang.reflect.Field.setAccessible(Field.java:174)
        at com.thoughtworks.xstream.core.util.Fields.locate(Fields.java:39)
        at com.thoughtworks.xstream.converters.collections.TreeMapConverter.<clinit>(TreeMapConverter.java:50)
        ... 90 more

Anything else?

No response

Error injecting: public org.apache.maven.repository.internal.DefaultVersionResolver org.apache.maven.repository.internal.DefaultVersionResolver.setRepositoryEventDispatcher(org.eclipse.aether.impl.RepositoryEventDispatcher)

Jenkins and plugins versions report

Environment
Paste the output here

What Operating System are you using (both controller, and any agents involved in the problem)?

macos

Reproduction steps

Running a JUnit test like this

    @Test
    public void mavenJob1() throws Exception {
        MavenModuleSet project = j.createProject(MavenModuleSet.class, "maven");
        Maven.MavenInstallation mavenInstallation = new Maven.MavenInstallation("test",
                "/usr/local/apache-maven-3.8" + ".5");
        project.getDescriptor().getMavenDescriptor().setInstallations(mavenInstallation);
        project.setMaven("test");
        //project.setScm(new SingleFileSCM("pom.xml", readResourceAsString("pom.xml")));
        Path resourceDirectory = Paths.get("src", "test", "resources");
        String absolutePath = resourceDirectory.toFile().getAbsolutePath();
        project.setCustomWorkspace(absolutePath.concat("/testNgFiles"));
        List<Action> actions = getDefaultActions();
        j.assertBuildStatus(Result.SUCCESS, project.scheduleBuild2(0, actions.toArray(new Action[0])));
    }

Expected Results

I should get the build output of Jenkins job

Actual Results

[Executor #0 for master : executing maven #1] WARN Sisu - Error injecting: org.apache.maven.artifact.resolver.DefaultArtifactResolver
com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting: public org.apache.maven.repository.internal.DefaultVersionResolver org.apache.maven.repository.internal.DefaultVersionResolver.setRepositoryEventDispatcher(org.eclipse.aether.impl.RepositoryEventDispatcher)
  at ClassRealm[maven, parent: ClassRealm[maven-parent, parent: null]] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule)
  while locating org.apache.maven.repository.internal.DefaultVersionResolver
  while locating java.lang.Object annotated with *
  at org.eclipse.sisu.wire.LocatorWiring
  while locating org.eclipse.aether.impl.VersionResolver
    for the 1st parameter of org.eclipse.aether.internal.impl.DefaultRepositorySystem.<init>(DefaultRepositorySystem.java:131)
  while locating org.eclipse.aether.internal.impl.DefaultRepositorySystem
  while locating java.lang.Object annotated with *
  while locating org.apache.maven.artifact.resolver.DefaultArtifactResolver

1 error
	at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1053)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
	at org.eclipse.sisu.space.AbstractDeferredClass.get(AbstractDeferredClass.java:48)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.eclipse.sisu.plexus.PlexusRequirements$RequirementProvider.get(PlexusRequirements.java:250)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
	at org.eclipse.sisu.space.AbstractDeferredClass.get(AbstractDeferredClass.java:48)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision(BeanScheduler.java:230)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:263)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:255)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:249)
	at hudson.maven.MavenEmbedder.lookup(MavenEmbedder.java:576)
	at hudson.maven.MavenEmbedder.getLocalRepository(MavenEmbedder.java:270)
	at hudson.maven.MavenEmbedder.buildMavenExecutionRequest(MavenEmbedder.java:166)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:121)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:110)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:137)
	at hudson.maven.MavenUtil.createEmbedder(MavenUtil.java:211)
	at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:1321)
	at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:1124)
	at hudson.FilePath.act(FilePath.java:1164)
	at hudson.FilePath.act(FilePath.java:1147)
	at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.parsePoms(MavenModuleSetBuild.java:985)
	at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:689)
	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:513)
	at hudson.model.Run.execute(Run.java:1907)
	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:543)
	at hudson.model.ResourceController.execute(ResourceController.java:97)
	at hudson.model.Executor.run(Executor.java:429)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.sisu.bean.BeanPropertySetter.set(BeanPropertySetter.java:78)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:62)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.wire.BeanProviders.firstOf(BeanProviders.java:179)
	at org.eclipse.sisu.wire.BeanProviders$7.get(BeanProviders.java:160)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:42)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:65)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:113)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:62)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.Guice4$1.get(Guice4.java:162)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.eclipse.sisu.plexus.PlexusRequirements$RequirementProvider.get(PlexusRequirements.java:250)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	... 67 more
[Executor #0 for master : executing maven #1] WARN Sisu - Error injecting: org.apache.maven.repository.legacy.LegacyRepositorySystem
com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting: public org.apache.maven.repository.internal.DefaultVersionResolver org.apache.maven.repository.internal.DefaultVersionResolver.setRepositoryEventDispatcher(org.eclipse.aether.impl.RepositoryEventDispatcher)
  at ClassRealm[maven, parent: ClassRealm[maven-parent, parent: null]] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule)
  while locating org.apache.maven.repository.internal.DefaultVersionResolver
  while locating java.lang.Object annotated with *
  at org.eclipse.sisu.wire.LocatorWiring
  while locating org.eclipse.aether.impl.VersionResolver
    for the 1st parameter of org.eclipse.aether.internal.impl.DefaultRepositorySystem.<init>(DefaultRepositorySystem.java:131)
  while locating org.eclipse.aether.internal.impl.DefaultRepositorySystem
  while locating java.lang.Object annotated with *
  while locating org.apache.maven.artifact.resolver.DefaultArtifactResolver
  at ClassRealm[maven, parent: ClassRealm[maven-parent, parent: null]] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule)
  while locating org.apache.maven.artifact.resolver.ArtifactResolver
  while locating org.apache.maven.repository.legacy.LegacyRepositorySystem

1 error
	at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1053)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
	at org.eclipse.sisu.space.AbstractDeferredClass.get(AbstractDeferredClass.java:48)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision(BeanScheduler.java:230)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:263)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:255)
	at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:249)
	at hudson.maven.MavenEmbedder.lookup(MavenEmbedder.java:576)
	at hudson.maven.MavenEmbedder.getLocalRepository(MavenEmbedder.java:270)
	at hudson.maven.MavenEmbedder.buildMavenExecutionRequest(MavenEmbedder.java:166)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:121)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:110)
	at hudson.maven.MavenEmbedder.<init>(MavenEmbedder.java:137)
	at hudson.maven.MavenUtil.createEmbedder(MavenUtil.java:211)
	at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:1321)
	at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:1124)
	at hudson.FilePath.act(FilePath.java:1164)
	at hudson.FilePath.act(FilePath.java:1147)
	at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.parsePoms(MavenModuleSetBuild.java:985)
	at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:689)
	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:513)
	at hudson.model.Run.execute(Run.java:1907)
	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:543)
	at hudson.model.ResourceController.execute(ResourceController.java:97)
	at hudson.model.Executor.run(Executor.java:429)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.sisu.bean.BeanPropertySetter.set(BeanPropertySetter.java:78)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:62)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.wire.BeanProviders.firstOf(BeanProviders.java:179)
	at org.eclipse.sisu.wire.BeanProviders$7.get(BeanProviders.java:160)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:42)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:65)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:113)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:62)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.Guice4$1.get(Guice4.java:162)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.eclipse.sisu.plexus.PlexusRequirements$RequirementProvider.get(PlexusRequirements.java:250)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
	at org.eclipse.sisu.space.AbstractDeferredClass.get(AbstractDeferredClass.java:48)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57)
	at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81)
	at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51)
	at org.eclipse.sisu.plexus.PlexusRequirements$RequirementProvider.get(PlexusRequirements.java:250)
	at org.eclipse.sisu.plexus.ProvidedPropertyBinding.injectProperty(ProvidedPropertyBinding.java:48)
	at org.eclipse.sisu.bean.BeanInjector.injectMembers(BeanInjector.java:52)
	at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:160)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
	... 38 more

Anything else?

No response

`@JenkinsRecipe` does not work with JUnit Jupiter extension

Jenkins and plugins versions report

Environment
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /usr/local/Cellar/maven/3.9.6/libexec
Java version: 17.0.9, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk@17/17.0.9/libexec/openjdk.jdk/Contents/Home
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "14.2.1", arch: "x86_64", family: "mac"

What Operating System are you using (both controller, and any agents involved in the problem)?

N/A

Reproduction steps

package org.jvnet.hudson.test.junit.jupiter;

import hudson.model.FreeStyleProject;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.JenkinsRecipe;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockFolder;

import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;

@WithJenkins
@JenkinsRuleRecipeExecutionTest.FreestyleJobRecipe("onClass")
public class JenkinsRuleRecipeExecutionTest {
    @Test
    void recipeOnClassIsExecuted(JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasSize(1));
        assertThat(rule.jenkins.getJobNames(), hasItem("onClass"));
    }

    @Test
    @FreestyleJobRecipe("onMethod")
    void recipeOnMethodIsExecuted(JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasItem("onMethod"));
    }

    @Test
    void recipeOnParameterIsExecuted(@FreestyleJobRecipe("onParameter") JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasItem("onParameter"));
    }

    @Test
    @FreestyleJobRecipe("onMethod")
    void allRecipesAreExecuted(@FreestyleJobRecipe("onParameter") JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasSize(3));
        assertThat(rule.jenkins.getJobNames(), hasItems("onClass", "onMethod", "onParameter"));
    }

    @Test
    @FreestyleJobRecipe("freestyleOnMethod")
    @MockFolderRecipe("folderOnMethod")
    void differentRecipesOnMethodAreExecuted(JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasItems("freestyleOnMethod", "folderOnMethod"));
    }

    @Test
    void differentRecipesOnParameterAreExecuted(
            @FreestyleJobRecipe("freestyleOnParam") @MockFolderRecipe("folderOnParam") JenkinsRule rule
    ) {
        assertThat(rule.jenkins.getJobNames(), hasItems("freestyleOnParam", "folderOnParam"));
    }

    @Test
    @ComposedRecipe
    void composedRecipeAreBothExecutedOnMethod(JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasItems("composedFreestyle", "composedFolder"));
    }

    @Test
    void composedRecipeAreBothExecutedOnParameter(@ComposedRecipe JenkinsRule rule) {
        assertThat(rule.jenkins.getJobNames(), hasItems("composedFreestyle", "composedFolder"));
    }

    @JenkinsRecipe(FreestyleJobRecipe.RecipeImpl.class)
    @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface FreestyleJobRecipe {
        String value();
        class RecipeImpl extends JenkinsRecipe.Runner<FreestyleJobRecipe> {
            @Override
            public void setup(JenkinsRule jenkinsRule, FreestyleJobRecipe recipe) throws Exception {
                jenkinsRule.createFreeStyleProject(recipe.value());
            }

            @Override
            public void decorateHome(JenkinsRule jenkinsRule, File home) throws Exception {
            }

            @Override
            public void tearDown(JenkinsRule jenkinsRule, FreestyleJobRecipe recipe) throws Exception {
                final FreeStyleProject item = jenkinsRule.jenkins.getItem(recipe.value(), jenkinsRule.jenkins, FreeStyleProject.class);
                assertThat(item, notNullValue());
                jenkinsRule.jenkins.remove(item);
            }
        }
    }

    @JenkinsRecipe(MockFolderRecipe.RecipeImpl.class)
    @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MockFolderRecipe {
        String value();
        class RecipeImpl extends JenkinsRecipe.Runner<MockFolderRecipe> {
            @Override
            public void setup(JenkinsRule jenkinsRule, MockFolderRecipe recipe) throws Exception {
                jenkinsRule.createFolder(recipe.value());
            }

            @Override
            public void decorateHome(JenkinsRule jenkinsRule, File home) throws Exception {
            }

            @Override
            public void tearDown(JenkinsRule jenkinsRule, MockFolderRecipe recipe) throws Exception {
                MockFolder item = jenkinsRule.jenkins.getItem(recipe.value(), jenkinsRule.jenkins, MockFolder.class);
                assertThat(item, notNullValue());
                jenkinsRule.jenkins.remove(item);
            }
        }
    }

    @FreestyleJobRecipe("composedFreestyle")
    @MockFolderRecipe("composedFolder")
    @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ComposedRecipe {
    }
}
mvn -Dtest=JenkinsRuleRecipeExecutionTest test

Expected Results

Tests (at least most of these) should be executed, and the recipe

Actual Results

[ERROR] Tests run: 8, Failures: 8, Errors: 0, Skipped: 0, Time elapsed: 8.040 s <<< FAILURE! -- in org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest
[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.composedRecipeAreBothExecutedOnMethod(JenkinsRule) -- Time elapsed: 4.021 s <<< FAILURE!
java.lang.AssertionError:

Expected: (a collection containing "composedFreestyle" and a collection containing "composedFolder")
     but: a collection containing "composedFreestyle" was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.composedRecipeAreBothExecutedOnMethod(JenkinsRuleRecipeExecutionTest.java:65)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.differentRecipesOnParameterAreExecuted(JenkinsRule) -- Time elapsed: 0.506 s <<< FAILURE!
java.lang.AssertionError:

Expected: (a collection containing "freestyleOnParam" and a collection containing "folderOnParam")
     but: a collection containing "freestyleOnParam" was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.differentRecipesOnParameterAreExecuted(JenkinsRuleRecipeExecutionTest.java:59)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnClassIsExecuted(JenkinsRule) -- Time elapsed: 0.842 s <<< FAILURE!
java.lang.AssertionError:

Expected: a collection with size <1>
     but: collection size was <0>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnClassIsExecuted(JenkinsRuleRecipeExecutionTest.java:26)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.composedRecipeAreBothExecutedOnParameter(JenkinsRule) -- Time elapsed: 0.498 s <<< FAILURE!
java.lang.AssertionError:

Expected: (a collection containing "composedFreestyle" and a collection containing "composedFolder")
     but: a collection containing "composedFreestyle" was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.composedRecipeAreBothExecutedOnParameter(JenkinsRuleRecipeExecutionTest.java:70)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.allRecipesAreExecuted(JenkinsRule) -- Time elapsed: 0.428 s <<< FAILURE!
java.lang.AssertionError:

Expected: a collection with size <3>
     but: collection size was <0>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.allRecipesAreExecuted(JenkinsRuleRecipeExecutionTest.java:44)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.differentRecipesOnMethodAreExecuted(JenkinsRule) -- Time elapsed: 0.528 s <<< FAILURE!
java.lang.AssertionError:

Expected: (a collection containing "freestyleOnMethod" and a collection containing "folderOnMethod")
     but: a collection containing "freestyleOnMethod" was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.differentRecipesOnMethodAreExecuted(JenkinsRuleRecipeExecutionTest.java:52)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnMethodIsExecuted(JenkinsRule) -- Time elapsed: 0.529 s <<< FAILURE!
java.lang.AssertionError:

Expected: a collection containing "onMethod"
     but: was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnMethodIsExecuted(JenkinsRuleRecipeExecutionTest.java:33)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

[ERROR] org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnParameterIsExecuted(JenkinsRule) -- Time elapsed: 0.656 s <<< FAILURE!
java.lang.AssertionError:

Expected: a collection containing "onParameter"
     but: was empty
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsRuleRecipeExecutionTest.recipeOnParameterIsExecuted(JenkinsRuleRecipeExecutionTest.java:38)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  • Additionally, it doesn't seem like the methods for each recipe implementation are appropriately being executed

Anything else?

Unclear to me which of these (and others) should thoeretically be supported by @JenkinsRecipe, or if a new JUnit Jupiter @*Recipe-escue annotation should be introduced

Are you interested in contributing a fix?

Yes - would like to know which of these test cases (and missing coverage) should be supported by the extension

WarExploder doesn't account for Gradle not always generating valid SHA1s in cache path

Jenkins and plugins versions report

Environment
Paste the output here

What Operating System are you using (both controller, and any agents involved in the problem)?

N/A

Reproduction steps

Try to run the test harness against jenkins-war:2.332.3.

Expected Results

Test harness functions properly.

Actual Results

WarExploder throws an AssertionError saying

~/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-war/2.332.3/48e994349a6ea9fff614dca79dd3c5f75c0f3d16/jenkins-war-2.332.3.war does not yet exist. Prime your development environment by running mvn validate.

This issue occurs because gradle's dependency caching trims leading zeros from the hash in the file cache. The SHA1 for jenkins-war 2.332.3 is 068b1e10fdddae7cad6f2b59c8c205d285321940 (see image)
image

but the file is stored on disk in ~/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-war/2.332.3/68b1e10fdddae7cad6f2b59c8c205d285321940/jenkins-war-2.332.3.war

This issue was raised with the gradle team in 2014 here with the response effectively being that it's an internal API with no guarantees.

I'd suggest implementing a conditional check to see if the directory hash is missing a character (stringified SHA1s are 40 characters and SHA256s are 64) that you prepend a 0 and test again.

Anything else?

No response

`HtmlFormUtil.getSubmitButton` picks wrong button for Jenkins config forms

Discovered in #702.

diff --git pom.xml pom.xml
index d4b87033d5..54dd8292c1 100644
--- pom.xml
+++ pom.xml
@@ -56,7 +56,7 @@ THE SOFTWARE.
 
   <properties>
     <changelist>999999-SNAPSHOT</changelist>
-    <jenkins.version>2.361</jenkins.version>
+    <jenkins.version>2.437</jenkins.version>
     <jmh.version>1.37</jmh.version>
     <gitHubRepo>jenkinsci/${project.artifactId}</gitHubRepo>
     <!-- Normally filled in by "maven-hpi-plugin" with the path to "org-netbeans-insane-hook.jar" extracted from this repository -->
diff --git src/main/java/org/htmlunit/html/HtmlFormUtil.java src/main/java/org/htmlunit/html/HtmlFormUtil.java
index c5bcccd75c..e696c9db67 100644
--- src/main/java/org/htmlunit/html/HtmlFormUtil.java
+++ src/main/java/org/htmlunit/html/HtmlFormUtil.java
@@ -50,6 +50,7 @@ public class HtmlFormUtil {
      */
     public static Page submit(final HtmlForm htmlForm) throws IOException {
         HtmlElement submitElement = getSubmitButton(htmlForm);
+        System.err.println("TODO submitElement=" + submitElement);
         return submit(htmlForm, submitElement);
     }
 
diff --git src/test/java/org/jvnet/hudson/test/SleepBuilderTest.java src/test/java/org/jvnet/hudson/test/SleepBuilderTest.java
index 1ae1b411a8..bab6aa6fef 100644
--- src/test/java/org/jvnet/hudson/test/SleepBuilderTest.java
+++ src/test/java/org/jvnet/hudson/test/SleepBuilderTest.java
@@ -14,8 +14,7 @@ public class SleepBuilderTest {
         FreeStyleProject project = j.createFreeStyleProject();
         SleepBuilder builder = new SleepBuilder(30);
         project.getBuildersList().add(builder);
-        j.configRoundtrip(project);
-        j.assertEqualDataBoundBeans(project.getBuildersList().get(SleepBuilder.class), builder);
+        j.configRoundtrip();
     }
 
 }

You might expect this to print the Save button. But that is not an <input type="submit">, it is some YUI craziness. Instead it picks

HtmlButton[<button tooltip="Copy home directory" text="/tmp/j h1749655323416403161" message="Copied" type="button" class="copy-button jenkins-button jenkins-button--tertiary jenkins-copy-button jenkins-!-margin-left-1" title="Copy home directory">]

And of course you do not want to click that. Yet it seems that HtmlForm.submit quietly accepts this and submits the form anyway.

`RealJenkinsRule` support for `executeOnServer`

Currently JenkinsRule.executeOnServer does not work from RealJenkinsRule, since ClosureExecuterAction is registered as an extension from test code, which is ignored.

The following works but is not thread-safe:

@SuppressWarnings("deprecation")
static <V> V executeOnServer(JenkinsRule r, Callable<V> c) throws Exception {
    ClosureExecuterAction cea = new ClosureExecuterAction();
    r.jenkins.getExtensionList(RootAction.class).add(cea);
    r.jenkins.getActions().add(cea);
    try {
        return r.executeOnServer(c);
    } finally {
        r.jenkins.getExtensionList(RootAction.class).remove(cea);
        r.jenkins.getActions().remove(cea);
    }
}

Jenkins-test-harness won't find jenkins war with Gradle 7.6

Jenkins and plugins versions report

Environment
n/a

What Operating System are you using (both controller, and any agents involved in the problem)?

Java

Reproduction steps

The jenkins test harness uses the following to locate the jenkins war file

// JENKINS-45245: work around incorrect test classpath in IDEA. Note that this will not correctly handle timestamped snapshots; in that case use `mvn test`.
File core = Which.jarFile(Jenkins.class); // will fail with IllegalArgumentException if have neither jenkins-war.war nor jenkins-core.jar in ${java.class.path}
String version = core.getParentFile().getName();
if (core.getName().equals("jenkins-core-" + version + ".jar") && core.getParentFile().getParentFile().getName().equals("jenkins-core")) {
war = new File(new File(new File(core.getParentFile().getParentFile().getParentFile(), "jenkins-war"), version), "jenkins-war-" + version + ".war");
if (!war.isFile()) {
throw new AssertionError(war + " does not yet exist. Prime your development environment by running `mvn validate`.");
}
LOGGER.log(Level.FINE, "{0} is the continuation of the classpath by other means", war);
} else {
throw new AssertionError(core + " is not in the expected location, and jenkins-war-*.war was not in " + System.getProperty("java.class.path"));
}

Gradle is using hashes in the local jar cache, https://discuss.gradle.org/t/how-are-hash-values-for-gradle-repositories-calculated/4345

So, this does not work with Gradle 7.6, because it assumes a directory hierarchy of a Maven local repository, but that version of Gradle has also the filehash in the path, so I get correct value for core, but wrong value for version:

core = /home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-core/2.361.2/46513df8e2016ef981a2608c9e362a5b3eab112e/jenkins-core-2.361.2.jar
version = 46513df8e2016ef981a2608c9e362a5b3eab112e

and now, core.getName().equals("jenkins-core-" + version + ".jar") && core.getParentFile().getParentFile().getName().equals("jenkins-core") has no chance of working, because first, version is wrong, and the path also misses one extra getParentFile().

Expected Results

Locate the war successfully even with Gradle 7.6.

Actual Results

Test timeout disabled.
=== Starting loadJenkinsCasCTest(io.strimzi.ci.integration.casc.JCasCTest)

/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-core/2.361.2/46513df8e2016ef981a2608c9e362a5b3eab112e/jenkins-core-2.361.2.jar is not in the expected location, and jenkins-war-*.war was not in /home/jdanek/.gradle/caches/7.6/workerMain/gradle-worker.jar:/home/jdanek/repos/testing/ci/msg-qe-cci/jobs/dsl/amq-clients/build/classes/groovy/test:/home/jdanek/repos/testing/ci/msg-qe-cci/jobs/dsl/amq-clients/build/resources/test:/home/jdanek/repos/testing/ci/msg-qe-cci/jobs/dsl/amq-clients/build/classes/groovy/main:/home/jdanek/repos/testing/ci/msg-qe-cci/jobs/dsl/amq-clients/build/resources/main:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-war/2.361.2/9b06767a2ca1cd96aa9686c766e4a83a2254e857/jenkins-war-2.361.2.war:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.main/jenkins-core/2.361.2/46513df8e2016ef981a2608c9e362a5b3eab112e/jenkins-core-2.361.2.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.plugins/job-dsl/1.81/5e62a0d531e92e67dfa47058b752909f1375396c/job-dsl-1.81.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.plugins/job-dsl-core/1.81/889444d2ff6f84418a1c21c5a31cb2a5786b1ab8/job-dsl-core-1.81.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/com.lesfurets/jenkins-pipeline-unit/1.14/a39ac387827541a0aaafc1a416cee48a049efe10/jenkins-pipeline-unit-1.14.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-ci.plugins/ghprb/1.42.2/c5771ab8986b02811a9e3fa587e20b6c99068eb1/ghprb-1.42.2.hpi:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.jenkins-

[...]

2.1/org.mozilla/rhino/1.7.7.2/a7c4a9ba8b6922374580d71060ef71eafa994256/rhino-1.7.7.2.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/javax.xml.stream/stax-api/1.0-2/d6337b0de8b25e53e81b922352fbea9f9f57ba0b/stax-api-1.0-2.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/pull-parser/pull-parser/2/c2f040085bfcd35963e9504bec11dac57cd0a86e/pull-parser-2.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/com.ibm.icu/icu4j/59.1/6f06e820cf4c8968bbbaae66ae0b33f6a256b57f/icu4j-59.1.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.apache.geronimo.specs/geronimo-jms_1.1_spec/1.1.1/c872b46c601d8dc03633288b81269f9e42762cea/geronimo-jms_1.1_spec-1.1.1.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/org.apache.geronimo.specs/geronimo-j2ee-management_1.1_spec/1.0.1/5372615b0c04c1913c95c34a0414cef720ca2855/geronimo-j2ee-management_1.1_spec-1.0.1.jar:/home/jdanek/.gradle/caches/modules-2/files-2.1/javax.activation/javax.activation-api/1.2.0/85262acf3ca9816f9537ca47d5adeabaead7cb16/javax.activation-api-1.2.0.jar
	at org.jvnet.hudson.test.WarExploder.findJenkinsWar(WarExploder.java:90)
	at org.jvnet.hudson.test.WarExploder.explode(WarExploder.java:116)
	at org.jvnet.hudson.test.WarExploder.getExplodedDir(WarExploder.java:56)
	at org.jvnet.hudson.test.JenkinsRule._createWebServer(JenkinsRule.java:803)
	at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:758)
	at org.jvnet.hudson.test.JenkinsRule.createWebServer(JenkinsRule.java:747)
	at org.jvnet.hudson.test.JenkinsRule.newHudson(JenkinsRule.java:699)
	at org.jvnet.hudson.test.JenkinsRule.before(JenkinsRule.java:415)
	at io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule.before(JenkinsConfiguredWithCodeRule.java:23)
	at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:608)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42)
	at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
	at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:72)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

Anything else?

I implemented the following workaround in my build.gradle.kts

tasks.named<Test>("test") {
    // set jenkins-war path as system property
    val artifact = testWar.resolvedConfiguration.resolvedArtifacts.find {
        it.moduleVersion.id.group == "org.jenkins-ci.main"
                && it.moduleVersion.id.module.name == "jenkins-war"
    }
    systemProperty("jth.jenkins-war.path", artifact!!.file.absolutePath)

    // ...
}

Upgrade HtmlUnit from 2.x.x to 3.x.x

Problem

The Jenkins test harness depends on an outdated release of HtmlUnit (at the time of this writing, 2.70.0).

Solution

Upgrade HtmlUnit from its current version (at the time of this writing, 2.70.0) to the latest version (at the time of this writing, 3.0.0) in jenkins-test-harness-htmlunit, jenkins-test-harness, plugin-pom, Stapler, and Jenkins core.

Implementation

Consult the Migrating from HtmlUnit 2.x.x to HtmlUnit 3.x.x documentation:

  1. Adjust the Maven group ID to org.htmlunit: ๐Ÿ‘‰ jenkinsci/jenkins-test-harness-htmlunit#110

    <dependency>
        <groupId>org.htmlunit</groupId>
        <artifactId>htmlunit</artifactId>
        <version>3.0.0</version>
    </dependency>
  2. Change all package name references from net.sourceforge.htmlunit to org.htmlunit: ๐Ÿ‘‰ #589

    import org.htmlunit.BrowserVersion;
    import org.htmlunit.WebClient;
    import org.htmlunit.html.HtmlInput;
    import org.htmlunit.html.HtmlPage;
  3. Update input control value access by replacing all usages of org.htmlunit.html.HtmlInput.getValueAttribute() with org.htmlunit.html.HtmlInput.getValue() and replacing all usages of org.htmlunit.html.HtmlInput.setValueAttribute(String) with org.htmlunit.html.HtmlInput.setValue(String).

Success criteria

The success criteria for this ticket are as follows:

  • jenkins-test-harness-htmlunit released with the latest version of HtmlUnit (at the time of this writing, 3.0.0) ๐Ÿ‘‰ jenkinsci/jenkins-test-harness-htmlunit#110
  • jenkins-test-harness upgraded to the abovementioned release of jenkins-test-harness-htmlunit ๐Ÿ‘‰ #589
  • plugin-pom upgraded to the abovementioned release of jenkins-test-harness
  • Stapler upgraded to the abovementioned release of jenkins-test-harness-htmlunit ๐Ÿ‘‰ jenkinsci/stapler#464
  • Jenkins core upgraded to the abovementioned release of jenkins-test-harness ๐Ÿ‘‰ jenkinsci/jenkins#8050
  • Weekly release shipped with all of the above changes

Allow RealJenkinsRule to use a war file

What feature do you want to see added?

RealJenkinsRule currently use the war in the classpath or war/target/jenkins.war. That war is reused by all rules in the test. To be able to use different wars per rule, a new withWar method has to be added.

Acceptance criteria:

  • The war file can be configure as part of the RealJenkinsRule configuration.
  • The dependencies from the pom.xml might be excluded easily.

Upstream changes

No response

Check compatibility of `RealJenkinsRule` with JaCoCo

If you enable test coverage in your plugin, does src/main/java/ exercised by RealJenkinsRule get counted?

Files.copy(snapshotManifest, plugins.toPath().resolve(shortName + ".jpl"));
means that the plugin under test will be loaded from target/classes/ (via target/test-classes/the.jpl), which should be instrumented. However the instrumented code would be running in another JVM and so results may not be collected. Does JaCoCo support such a scenario?

`DirectoryNotEmptyException` thrown by `TemporaryDirectoryAllocator#dispose` in `JenkinsRule#after` on Windows

Jenkins and plugins versions report

Currently only happens on ci.jenkins.io and can not be reproduced on my local Windows machine.

What Operating System are you using (both controller, and any agents involved in the problem)?

Windows

Reproduction steps

Have a JUnit5 test with JenkinsRule running a Job
Job directory is not being deleted properly in JenkinsRule#after

See test code

See failing test

Expected Results

Job directory is being cleaned up or there is no exception thrown if it fails and the test succeeds.

Actual Results

DirectoryNotEmptyException is thrown in JenkinsRule#after (causing an IOException with an empty exception message) and test fails

Stacktrace:

java.io.IOException: 
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:144)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:131)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.dispose(TemporaryDirectoryAllocator.java:99)
	at org.jvnet.hudson.test.TestEnvironment.dispose(TestEnvironment.java:84)
	at org.jvnet.hudson.test.JenkinsRule.after(JenkinsRule.java:524)
	at org.jvnet.hudson.test.junit.jupiter.JenkinsExtension.afterEach(JenkinsExtension.java:26)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$12(TestMethodTestDescriptor.java:260)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:276)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:276)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:275)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:259)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:144)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:120)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
Caused by: java.nio.file.DirectoryNotEmptyException: C:\Jenkins\workspace\s_custom-folder-icon-plugin_main\target\tmp\j h12616395869530307222\jobs\folder\jobs\Success\builds\2
	at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:271)
	at java.base/sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:110)
	at java.base/java.nio.file.Files.deleteIfExists(Files.java:1181)
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.delete(TemporaryDirectoryAllocator.java:141)
	... 67 more

Anything else?

Since this is not reliably reproducible and only happens on Windows I suspect something like a slow filesystem being the root cause.
For some reason the message of the IOException that is thrown in my test is empty, even though it should have the path in it. For me a strong indicator that the files were actually deleted but the filesystem was too slow.

However I personally do not see a reason why a test should fail because of this in the first place ๐Ÿค”
Comparing TemporaryDirectoryAllocator#dispose and TemporaryDirectoryAllocator#disposeAsync it shows to me that logging the IOException thrown is just fine.

Maybe use java.io.File.deleteOnExit() as a last remedy instead?

Error: Could not initialize class org.jvnet.hudson.test.TestPluginManager

Jenkins and plugins versions report

I'm getting the following error, when trying to initialize JenkinsRule:

java.lang.NoClassDefFoundError: Could not initialize class org.jvnet.hudson.test.TestPluginManager
	at org.jvnet.hudson.test.JenkinsRule.<init>(JenkinsRule.java:344)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at de.akdb.pers.ci.JobScriptsSpec.$spock_initializeSharedFields(JobScriptsSpec.groovy:16)
Environment

Here are my Gradle dependencies:

ext {
  jobDslVersion = '1.81'
  jenkinsVersion = '2.375.3'
}

configurations {
  testPlugins {}
}

dependencies {
  implementation 'org.codehaus.groovy:groovy-all:2.4.17'
  implementation 'org.spockframework:spock-core:1.0-groovy-2.4'

  // Jenkins test harness dependencies
  testImplementation 'org.jenkins-ci.main:jenkins-test-harness:1949.vb_b_37feefe78c'
  testImplementation "org.jenkins-ci.main:jenkins-war:${jenkinsVersion}"

  // Job DSL plugin including plugin dependencies
  implementation "org.jenkins-ci.plugins:job-dsl-core:${jobDslVersion}"
  implementation "org.jenkins-ci.plugins:job-dsl:${jobDslVersion}@jar"
  testImplementation 'org.jenkins-ci.plugins:structs:1.20@jar'

  implementation 'org.xmlunit:xmlunit-core:2.5.1'

  testPlugins 'org.jenkins-ci.plugins:structs:1.20'
  testPlugins 'io.jenkins.plugins:warnings-ng:10.0.3'
}

I also got the same error with the version jenkins-test-harness:2.56. Also i found this stackoverflow question with the same problem: https://stackoverflow.com/questions/51724860/jenkins-job-failed-with-error-java-lang-noclassdeffounderror , sadly without an answer.

Here is my test, that initializes JenkinsRule:

package de.akdb.pers.ci

import groovy.io.FileType
import javaposse.jobdsl.dsl.DslScriptLoader
import javaposse.jobdsl.plugin.JenkinsJobManagement
import jenkins.model.Jenkins
import org.junit.ClassRule
import org.jvnet.hudson.test.JenkinsRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

class JobScriptsSpec extends Specification {
    @Shared
    @ClassRule
    JenkinsRule jenkinsRule = new JenkinsRule()

    @Unroll
    def 'test script #file.name'(File file) {
        given:
        def jobManagement = new JenkinsJobManagement(System.out, [:], new File('.'))

        when:
        new DslScriptLoader(jobManagement).runScript(file.text)

        then:
        noExceptionThrown()

        where:
        file << jobFiles
    }

    static List<File> getJobFiles() {
        List<File> files = []
        new File('jobs').eachFileRecurse {
            if (it.name.endsWith('.groovy')) {
                files << it
            }
        }
        files
    }
}

Am i doing something wrong? Is the JDK version I'm using a problem?

What Operating System are you using (both controller, and any agents involved in the problem)?

OS: Windows Server 2019
JDK: Eclipse Adoptium jdk-17.0.3.7
Gradle: 8.0.2

Reproduction steps

Initializing JenkinsRule

Expected Results

works

Actual Results

doesn't work

Anything else?

No response

`java.net.BindException`: Address already in use in `checks-api-plugin`, `font-awesome-api-plugin`, and `forensics-api-plugin`

Jenkins and plugins versions report

Apache Maven 3.9.6
Java version: 21.0.1, vendor: Eclipse Adoptium
OS name: "linux", version: "5.15.0-91-generic"

What Operating System are you using (both controller, and any agents involved in the problem)?

Apache Maven 3.9.6
Java version: 21.0.1, vendor: Eclipse Adoptium
OS name: "linux", version: "5.15.0-91-generic"

Reproduction steps

mvn clean verify -Djenkins-test-harness.version=2115.v0d2b_4a_a_e80f8

Expected Results

Tests pass

Actual Results

Tests fail with exception noted in #689 (comment)

Anything else?

Tests pass with mvn clean verify -Djenkins-test-harness.version=2112.ve584e0edc63b_

Are you interested in contributing a fix?

No

Test-only plugin from source in `RealJenkinsRule`

JenkinsRule tests commonly use @TestExtension to define mock implementations of various APIs, which is a very powerful system. For RealJenkinsRule, there is no direct equivalent. As

* <li>Possibly {@link ExtensionList#add(Object)} can be used as an alternative to {@link TestExtension}.
hints at, you can define new types in test sources and load them in a Jenkins JVM, and even register them programmatically with ExtensionList.add (suppressing the deprecation warning), but they will be defined in an unusual class loader (not UberClassLoader) and there may be other reasons why the test cannot be made to pass or would not be convincing if it did.

๐Ÿค” There could be a system whereby you could define a src/test/java/some/dedicated/pkg/package-info.java with a SOURCE-retention annotation directing a processor to create a target/test-classes/plugins/some-dedicated-pkg.jpi which could be included in addPlugins.

* @param plugins Filenames of the plugins to install. These are expected to be absolute test classpath resources,
* such as {@code plugins/workflow-job.hpi} for example.
* <p>Committing that file to SCM (say, {@code src/test/resources/sample.jpi}) is
* reasonable for small fake plugins built for this purpose and exercising some bit of code.
* If you wish to test with larger archives of real plugins, this is possible for example by
* binding {@code dependency:copy} to the {@code process-test-resources} phase.
notes that when you do this today, you must commit the plugin binary to Git, making the test harder to review and maintain.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

regex
Jenkinsfile
  • org.jenkins-ci.main:jenkins-war 2.460

  • Check this box to trigger a request for Renovate to run again on this repository

i can initialize spock test

Jenkins and plugins versions report

with gradle 8.6 and jdk11
//build.gradle
Plugins {
    id 'groovy'
}

sourceSets {
    jobs {
        groovy {
            srcDirs 'src/jobs'
            compileClasspath += main.compileClasspath
        }
        compileClasspath += sourceSets.main.output
        runtimeClasspath += sourceSets.main.output
    }
    src {
        groovy {
            srcDir 'src/main/groovy'
        }
    }
    test {
        groovy {
            srcDir 'src/test/groovy'
        }
    }
}

repositories {
    mavenCentral()
    maven { url 'https://repo.jenkins-ci.org/releases/' }
    jcenter{url "https://jcenter.bintray.com/"}
}

configurations {
    testPlugins {}

    // see JENKINS-45512
    testCompile {
        exclude group: 'xalan'
        exclude group: 'xerces'
    }
}

configurations.all*.exclude group: 'xalan'

dependencies {
    implementation 'org.codehaus.groovy:groovy:2.5.14'
    implementation ("org.jenkins-ci.plugins:job-dsl-core:${jobDslVersion}") {
        exclude module: 'xstream'
    }


    testCompile 'org.spockframework:spock-core:1.3-groovy-2.5'
    testImplementation 'org.spockframework:spock-core:2.0-M5-groovy-3.0'
    testImplementation 'cglib:cglib-nodep:2.2.2' // used by Spock

    // Jenkins test harness dependencies
    testImplementation('org.jenkins-ci.main:jenkins-test-harness:2146.v6b_f8b_1cb_d12d') { //2.34 2146.v6b_f8b_1cb_d12d
        exclude group: 'org.netbeans.modules', module: 'org-netbeans-insane' 
    }
    testImplementation("org.jenkins-ci.main:jenkins-war:${jenkinsVersion}") {
        exclude group: 'org.jenkins-ci.ui', module: 'bootstrap' 
    }
    testCompile("org.jenkins-ci.main:jenkins-war:${jenkinsVersion}") {
        exclude group: 'org.jenkins-ci.ui', module: 'bootstrap' 
    }

    // Job DSL plugin including plugin dependencies
    testImplementation "org.jenkins-ci.plugins:job-dsl:${jobDslVersion}"
    testImplementation "org.jenkins-ci.plugins:job-dsl:${jobDslVersion}@jar"
    testImplementation 'org.jenkins-ci.plugins:structs:1.20@jar'
    testImplementation 'org.jenkins-ci.plugins:script-security:1.54@jar'
    testImplementation "org.jenkins-ci.main:jenkins-core:${jenkinsVersion}"
    testCompile "org.jenkins-ci.plugins:job-dsl:${jobDslVersion}"
    testCompile "org.jenkins-ci.plugins:job-dsl:${jobDslVersion}@jar"
    testCompile 'org.jenkins-ci.plugins:structs:1.20@jar'
    testCompile 'org.jenkins-ci.plugins:script-security:1.54@jar'

    // Plugins to install in test instance
    testPlugins 'org.jenkins-ci.plugins:cloudbees-folder:5.14'
    testPlugins 'org.jenkins-ci.plugins:credentials:2.1.10'
    testPlugins 'org.jenkins-ci.plugins:cvs:2.13'
    testPlugins 'org.jenkins-ci.plugins:ghprb:1.40.0'
    testPlugins 'org.jenkins-ci.plugins:token-macro:2.5'
    testPlugins 'org.jenkins-ci.plugins.workflow:workflow-cps-global-lib:2.7'


}

task resolveTestPlugins(type: Copy) {
    from configurations.testPlugins
    into new File(sourceSets.test.output.resourcesDir, 'test-dependencies')
    include '*.hpi'
    include '*.jpi'
    def mapping = [:]

    doFirst {
        configurations.testPlugins.resolvedConfiguration.resolvedArtifacts.each {
            mapping[it.file.name] = "${it.name}.${it.extension}"
        }
    }
    rename { mapping[it] }

    doLast {
        List<String> baseNames = source*.name.collect { mapping[it] }.collect { it[0..it.lastIndexOf('.') - 1] }
        new File(destinationDir, 'index').setText(baseNames.join('\n'), 'UTF-8')
    }
}

test {
    dependsOn tasks.resolveTestPlugins
    inputs.files sourceSets.jobs.groovy.srcDirs
    useJUnitPlatform()
}

#gradle.properties
jobDslVersion=1.77
jenkinsVersion= 2.445
//JobRulesSpec.groovy
package net.regnology

import groovy.util.FileNameFinder
import javaposse.jobdsl.dsl.DslScriptLoader
import javaposse.jobdsl.plugin.JenkinsJobManagement
import org.junit.ClassRule
import org.jvnet.hudson.test.JenkinsRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

class JobRulesSpec extends Specification {
    @Shared
    @ClassRule
    private JenkinsRule jenkinsRule = new JenkinsRule()

    @Unroll
    def 'test script #file.name'() { //File file
        given:
        println "==============> ${jenkinsRule.jenkins}"
        def jobManagement = new JenkinsJobManagement(System.out, [:], new File('.'))

        when:
        new DslScriptLoader(jobManagement).runScript(file.text)

        then:
        noExceptionThrown()

        where:
        file << new FileNameFinder().getFileNames('src/jobs', '**/*.groovy').collect { new File(it) }
    }
}

result of test

<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="net.regnology.JobRulesSpec" tests="1" skipped="0" failures="1" errors="0" timestamp="2024-02-19T16:33:05" hostname="INV-PC-432" time="0.833">
  <properties/>
  <testcase name="test script job.groovy" classname="net.regnology.JobRulesSpec" time="0.833">
    <failure message="Expected no exception to be thrown, but got 'java.lang.IllegalStateException'" type="org.spockframework.runtime.UnallowedExceptionThrownError">Expected no exception to be thrown, but got 'java.lang.IllegalStateException'
	at app//spock.lang.Specification.noExceptionThrown(Specification.java:118)
	at net.regnology.JobRulesSpec.test script #file.name(jobsRulesSpec.groovy:27)
Caused by: java.lang.IllegalStateException: Jenkins.instance is missing. Read the documentation of Jenkins.getInstanceOrNull to see what you are doing wrong.
	at jenkins.model.Jenkins.get(Jenkins.java:819)
	at javaposse.jobdsl.plugin.LookupStrategy.lambda$static$0(LookupStrategy.java:19)
	at javaposse.jobdsl.plugin.LookupStrategy.getContext(LookupStrategy.java:57)
	at javaposse.jobdsl.plugin.LookupStrategy.getItem(LookupStrategy.java:42)
	at javaposse.jobdsl.plugin.JenkinsJobManagement.createOrUpdateConfig(JenkinsJobManagement.java:136)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs_closure4(AbstractDslScriptLoader.groovy:204)
	at groovy.lang.Closure.call(Closure.java:412)
	at groovy.lang.Closure.call(Closure.java:428)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs(AbstractDslScriptLoader.groovy:197)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedItems(AbstractDslScriptLoader.groovy:184)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts_closure1(AbstractDslScriptLoader.groovy:63)
	at groovy.lang.Closure.call(Closure.java:412)
	at groovy.lang.Closure.call(Closure.java:428)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:46)
	at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScript(AbstractDslScriptLoader.groovy:87)
	at net.regnology.JobRulesSpec.test script #file.name(jobsRulesSpec.groovy:24)
</failure>
  </testcase>
  <system-out><![CDATA[==============> null
Processing provided DSL script
]]></system-out>
  <system-err><![CDATA[Feb 19, 2024 5:33:06 PM javaposse.jobdsl.plugin.JenkinsJobManagement createOrUpdateConfig
INFO: createOrUpdateConfig for test
]]></system-err>
</testsuite>


</details>
```


### What Operating System are you using (both controller, and any agents involved in the problem)?

window

### Reproduction steps

run ./gradlew clean test

### Expected Results

test new to succes

### Actual Results

my test failed

### Anything else?

_No response_

### Are you interested in contributing a fix?

_No response_

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.