Skip to content

Commit 1de8c91

Browse files
authored
MCOMPILER 346 workaround to jdk bug: assertion error from javaxcompiler javax.tools API (#97)
* [MCOMPILER-346] use plexus-compiler snapshot to avoid jdk bug add an it for it * use release 2.11.0 of plexus-compilers Signed-off-by: Olivier Lamy <[email protected]>
1 parent 96ed94f commit 1de8c91

File tree

5 files changed

+321
-1
lines changed

5 files changed

+321
-1
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ under the License.
6868
! The following property is used in the integration tests MCOMPILER-157
6969
-->
7070
<mavenPluginPluginVersion>3.5</mavenPluginPluginVersion>
71-
<plexusCompilerVersion>2.10.0</plexusCompilerVersion>
71+
<plexusCompilerVersion>2.11.0</plexusCompilerVersion>
7272

7373
<groovyVersion>2.4.21</groovyVersion>
7474
<groovyEclipseCompilerVersion>3.7.0</groovyEclipseCompilerVersion>
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.java.version = 11+
19+
invoker.goals = clean compile
20+
invoker.buildResult = failure

src/it/MCOMPILER-346/pom.xml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
~ Licensed to the Apache Software Foundation (ASF) under one
5+
~ or more contributor license agreements. See the NOTICE file
6+
~ distributed with this work for additional information
7+
~ regarding copyright ownership. The ASF licenses this file
8+
~ to you under the Apache License, Version 2.0 (the
9+
~ "License"); you may not use this file except in compliance
10+
~ with the License. You may obtain a copy of the License at
11+
~
12+
~ http://www.apache.org/licenses/LICENSE-2.0
13+
~
14+
~ Unless required by applicable law or agreed to in writing,
15+
~ software distributed under the License is distributed on an
16+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
~ KIND, either express or implied. See the License for the
18+
~ specific language governing permissions and limitations
19+
~ under the License.
20+
-->
21+
22+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
<modelVersion>4.0.0</modelVersion>
24+
<groupId>com.basilcrow</groupId>
25+
<artifactId>MCOMPILER-346-mre</artifactId>
26+
<version>1.0</version>
27+
<packaging>jar</packaging>
28+
<name>MCOMPILER-346 Minimal Reproducible Example (MRE)</name>
29+
<url>https://github.com/basil/MCOMPILER-346-mre</url>
30+
<properties>
31+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
32+
</properties>
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.eclipse.sisu</groupId>
36+
<artifactId>org.eclipse.sisu.plexus</artifactId>
37+
<version>0.2.0</version>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.jenkins-ci.main</groupId>
41+
<artifactId>remoting</artifactId>
42+
<version>3.2</version>
43+
</dependency>
44+
</dependencies>
45+
<repositories>
46+
<repository>
47+
<id>repo.jenkins-ci.org</id>
48+
<url>https://repo.jenkins-ci.org/public/</url>
49+
</repository>
50+
</repositories>
51+
<build>
52+
<plugins>
53+
<plugin>
54+
<groupId>org.apache.maven.plugins</groupId>
55+
<artifactId>maven-compiler-plugin</artifactId>
56+
<version>@project.version@</version>
57+
<configuration>
58+
<release>11</release>
59+
</configuration>
60+
</plugin>
61+
</plugins>
62+
</build>
63+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package org.jenkinsci.test.acceptance.server;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import javax.inject.Inject;
23+
import java.io.File;
24+
import java.io.IOException;
25+
import java.net.URL;
26+
import java.util.LinkedList;
27+
import java.util.List;
28+
import java.util.concurrent.Executors;
29+
30+
import org.jenkinsci.remoting.RoleChecker;
31+
import org.jenkinsci.test.acceptance.controller.IJenkinsController;
32+
import org.jenkinsci.test.acceptance.controller.JenkinsController;
33+
import org.jenkinsci.test.acceptance.controller.LocalController.LocalFactoryImpl;
34+
import org.jenkinsci.test.acceptance.log.LogListenable;
35+
import org.jenkinsci.test.acceptance.log.LogListener;
36+
import org.jenkinsci.test.acceptance.log.LogSplitter;
37+
38+
import com.cloudbees.sdk.extensibility.Extension;
39+
import com.google.inject.Injector;
40+
41+
import hudson.remoting.Callable;
42+
import hudson.remoting.Channel;
43+
import hudson.remoting.Channel.Mode;
44+
import hudson.remoting.ChannelBuilder;
45+
import jnr.unixsocket.UnixSocketAddress;
46+
import jnr.unixsocket.UnixSocketChannel;
47+
import static java.lang.System.*;
48+
49+
/**
50+
* {@link JenkinsController} that talks to {@link JenkinsControllerPoolProcess} over Unix domain socket.
51+
*
52+
* @author Kohsuke Kawaguchi
53+
*/
54+
public class PooledJenkinsController extends JenkinsController implements LogListenable {
55+
private URL url;
56+
private final File socket;
57+
private UnixSocketChannel conn;
58+
private final LogSplitter splitter = new LogSplitter();
59+
private Channel channel;
60+
private IJenkinsController controller;
61+
private final List<byte[]> toUnpack = new LinkedList<>();
62+
63+
public PooledJenkinsController(Injector i, File socket) {
64+
super(i);
65+
this.socket = socket;
66+
}
67+
68+
@Override
69+
public void addLogListener(LogListener l) {
70+
splitter.addLogListener(l);
71+
}
72+
73+
@Override
74+
public void removeLogListener(LogListener l) {
75+
splitter.removeLogListener(l);
76+
}
77+
78+
private boolean connect() throws IOException {
79+
if (conn != null) return false;
80+
81+
System.out.println("Requesting jut instance using socket " + socket.getAbsolutePath());
82+
UnixSocketAddress address = new UnixSocketAddress(socket);
83+
conn = UnixSocketChannel.open(address);
84+
85+
channel = new ChannelBuilder("JenkinsPool", Executors.newCachedThreadPool())
86+
.withMode(Mode.BINARY)
87+
.build(ChannelStream.in(conn), ChannelStream.out(conn));
88+
89+
try {
90+
controller = (IJenkinsController)channel.waitForRemoteProperty("controller");
91+
controller.start();
92+
url = controller.getUrl();
93+
94+
if (!isQuite) {
95+
splitter.addLogListener(getLogPrinter());
96+
}
97+
98+
final LogListener l = channel.export(LogListener.class, splitter);
99+
channel.call(new InstallLogger(controller,l));
100+
101+
for (byte[] content : toUnpack) {
102+
controller.populateJenkinsHome(content, false);
103+
}
104+
toUnpack.clear();
105+
} catch (InterruptedException e) {
106+
throw new IOException(e);
107+
}
108+
109+
return true;
110+
}
111+
112+
@Override
113+
public void startNow() throws IOException {
114+
connect();
115+
}
116+
117+
@Override
118+
public void stopNow() throws IOException {
119+
controller.stop();
120+
}
121+
122+
@Override
123+
public void populateJenkinsHome(byte[] template, boolean clean) throws IOException {
124+
if (controller != null) {
125+
controller.populateJenkinsHome(template, clean);
126+
} else {
127+
if (clean) {
128+
throw new UnsupportedOperationException("clean mode unsupported for now");
129+
}
130+
toUnpack.add(template);
131+
}
132+
}
133+
134+
@Override
135+
public URL getUrl() {
136+
if (url==null)
137+
throw new IllegalStateException("This controller has not been started");
138+
return url;
139+
}
140+
141+
@Override
142+
public void tearDown() throws IOException {
143+
channel.close();
144+
try {
145+
channel.join(3000);
146+
} catch (InterruptedException e) {
147+
throw new IOException(e);
148+
} finally {
149+
if (conn !=null)
150+
conn.close();
151+
conn = null;
152+
}
153+
}
154+
155+
@Override
156+
public void diagnose(Throwable cause) {
157+
// TODO: Report jenkins log
158+
cause.printStackTrace(out);
159+
if(getenv("INTERACTIVE") != null && getenv("INTERACTIVE").equals("true")){
160+
out.println("Commencing interactive debugging. Browser session was kept open.");
161+
out.println("Press return to proceed.");
162+
try {
163+
in.read();
164+
} catch (IOException e) {
165+
throw new RuntimeException(e);
166+
}
167+
}
168+
}
169+
170+
@Extension
171+
public static class FactoryImpl extends LocalFactoryImpl {
172+
@Inject Injector i;
173+
174+
@Override
175+
public String getId() {
176+
return "pool";
177+
}
178+
179+
@Override
180+
public JenkinsController create() {
181+
return i.getInstance(PooledJenkinsController.class);
182+
}
183+
}
184+
185+
/**
186+
* Runs on the pool server to install logger.
187+
*/
188+
private static class InstallLogger implements Callable<Void, IOException> {
189+
private final IJenkinsController controller;
190+
private final LogListener l;
191+
192+
private InstallLogger(IJenkinsController controller, LogListener l) {
193+
this.controller = controller;
194+
this.l = l;
195+
}
196+
197+
@Override
198+
public Void call() throws IOException {
199+
if (controller instanceof LogListenable) {
200+
LogListenable ll = (LogListenable) controller;
201+
ll.addLogListener(l);
202+
}
203+
return null;
204+
}
205+
206+
@Override
207+
public void checkRoles(RoleChecker checker) throws SecurityException {
208+
}
209+
210+
private static final long serialVersionUID = 1L;
211+
}
212+
}

src/it/MCOMPILER-346/verify.groovy

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
def logFile = new File( basedir, 'build.log' )
21+
assert logFile.exists()
22+
content = logFile.text
23+
24+
assert content.contains( 'package org.jenkinsci.test.acceptance.controller does not exist' )
25+
assert content.contains( 'package org.jenkinsci.test.acceptance.log does not exist' )

0 commit comments

Comments
 (0)