New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NO_MERGE] [JENKINS-54905] - Experimental branch for Java 11 support #41
Changes from all commits
7dfcd4d
08e6f49
bf42f17
d14b591
ebb47d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Dockerfile | ||
**/target | ||
demo | ||
test |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,14 +14,14 @@ buildSettings: | |
source: | ||
dir: ../.. | ||
docker: | ||
base: "jenkins/jenkins:2.138.2" | ||
base: "jenkins/jenkins-experimental:latest-jdk11" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't you want to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed |
||
tag: "jenkins-experimental/jenkinsfile-runner-demo" | ||
build: true | ||
war: | ||
groupId: "org.jenkins-ci.main" | ||
artifactId: "jenkins-war" | ||
source: | ||
version: "2.138.2" | ||
version: "2.149" | ||
plugins: | ||
- groupId: "org.jenkins-ci.plugins.workflow" | ||
artifactId: "workflow-job" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
pipeline-model-definition:latest | ||
workflow-support:incrementals;org.jenkins-ci.plugins.workflow;2.21-rc591.43d37d4d080a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might make sense to bump to |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package io.jenkins.jenkinsfile.runner; | ||
|
||
import com.sun.org.apache.bcel.internal.util.ClassLoader; | ||
import hudson.security.ACL; | ||
import io.jenkins.jenkinsfile.runner.util.JoinClassLoader; | ||
import jenkins.slaves.DeprecatedAgentProtocolMonitor; | ||
import org.eclipse.jetty.security.HashLoginService; | ||
import org.eclipse.jetty.security.LoginService; | ||
|
@@ -14,6 +16,7 @@ | |
|
||
import javax.servlet.ServletContext; | ||
import java.io.File; | ||
import java.net.URLClassLoader; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.logging.Level; | ||
|
@@ -37,6 +40,11 @@ public JenkinsfileRunnerRule(File warDir, File pluginsDir) { | |
this.pluginsDir = pluginsDir; | ||
} | ||
|
||
private static boolean isPostJava8() { | ||
String javaVersion = System.getProperty("java.version"); | ||
return !javaVersion.startsWith("1."); | ||
} | ||
|
||
/** | ||
* Sets up Jetty without any actual TCP port serving HTTP. | ||
*/ | ||
|
@@ -46,7 +54,16 @@ protected ServletContext createWebServer() throws Exception { | |
server = new Server(queuedThreadPool); | ||
|
||
WebAppContext context = new WebAppContext(warDir.getPath(), contextPath); | ||
context.setClassLoader(getClass().getClassLoader()); | ||
String javaVersion = System.getProperty("java.version"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused, I guess leftover from the new |
||
|
||
// if (javaVersion.startsWith("1.")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove the commented out code? Also, if you mean to keep it, then I guess you'd use |
||
// context.setClassLoader(getClass().getClassLoader()); | ||
// } else { | ||
ClassLoader platform = (ClassLoader) ClassLoader.class.getMethod("getPlatformClassLoader").invoke(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have a comment explaining the intent a bit here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes please! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC, the goal here is get exactly the same classloader as in previous JDK versions. Since this piece of code is executed always and not only with java11, what will happen if this code is executed with java8? The |
||
java.lang.ClassLoader cl = new JoinClassLoader(getClass().getClassLoader(), platform); | ||
context.setClassLoader(cl); | ||
// } | ||
|
||
context.setConfigurations(new Configuration[]{new WebXmlConfiguration()}); | ||
context.addBean(new NoListenerConfiguration(context)); | ||
server.setHandler(context); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package io.jenkins.jenkinsfile.runner.util;// Copyright 2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland | ||
// www.source-code.biz, www.inventec.ch/chdh | ||
// | ||
// This module is multi-licensed and may be used under the terms | ||
// of any of the following licenses: | ||
// | ||
// LGPL, GNU Lesser General Public License, V2 or later, http://www.gnu.org/licenses/lgpl.html | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this code is not compatible w.r.t the license. I put it here only for the experiment (which does not work so far), and it should not be merged as is |
||
// AL, Apache License, V2.0 or later, http://www.apache.org/licenses | ||
// | ||
// Please contact the author if you need another license. | ||
// This module is provided "as is", without warranties of any kind. | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.URL; | ||
import java.nio.ByteBuffer; | ||
import java.security.SecureClassLoader; | ||
import java.util.Enumeration; | ||
import java.util.Vector; | ||
|
||
/** | ||
* A class loader that combines multiple class loaders into one.<br> | ||
* The classes loaded by this class loader are associated with this class loader, | ||
* i.e. Class.getClassLoader() points to this class loader. | ||
*/ | ||
public class JoinClassLoader extends ClassLoader { | ||
|
||
private ClassLoader[] delegateClassLoaders; | ||
|
||
public JoinClassLoader (ClassLoader parent, ClassLoader... delegateClassLoaders) { | ||
super(parent); | ||
this.delegateClassLoaders = delegateClassLoaders; } | ||
|
||
protected Class<?> findClass (String name) throws ClassNotFoundException { | ||
// It would be easier to call the loadClass() methods of the delegateClassLoaders | ||
// here, but we have to load the class from the byte code ourselves, because we | ||
// need it to be associated with our class loader. | ||
String path = name.replace('.', '/') + ".class"; | ||
URL url = findResource(path); | ||
if (url == null) { | ||
throw new ClassNotFoundException(name); } | ||
ByteBuffer byteCode; | ||
try { | ||
byteCode = loadResource(url); } | ||
catch (IOException e) { | ||
throw new ClassNotFoundException(name, e); } | ||
return defineClass(name, byteCode, null); } | ||
|
||
private ByteBuffer loadResource (URL url) throws IOException { | ||
InputStream stream = null; | ||
try { | ||
stream = url.openStream(); | ||
int initialBufferCapacity = Math.min(0x40000, stream.available() + 1); | ||
if (initialBufferCapacity <= 2) { | ||
initialBufferCapacity = 0x10000; } | ||
else { | ||
initialBufferCapacity = Math.max(initialBufferCapacity, 0x200); } | ||
ByteBuffer buf = ByteBuffer.allocate(initialBufferCapacity); | ||
while (true) { | ||
if (!buf.hasRemaining()) { | ||
ByteBuffer newBuf = ByteBuffer.allocate(2*buf.capacity()); | ||
buf.flip(); | ||
newBuf.put(buf); | ||
buf = newBuf; } | ||
int len = stream.read(buf.array(), buf.position(), buf.remaining()); | ||
if (len <= 0) { | ||
break; } | ||
buf.position(buf.position()+len); } | ||
buf.flip(); | ||
return buf; } | ||
finally { | ||
if (stream != null) { | ||
stream.close(); }}} | ||
|
||
protected URL findResource (String name) { | ||
for (ClassLoader delegate : delegateClassLoaders) { | ||
URL resource = delegate.getResource(name); | ||
if (resource != null) { | ||
return resource; }} | ||
return null; } | ||
|
||
protected Enumeration<URL> findResources (String name) throws IOException { | ||
Vector<URL> vector = new Vector<URL>(); | ||
for (ClassLoader delegate : delegateClassLoaders) { | ||
Enumeration<URL> enumeration = delegate.getResources(name); | ||
while (enumeration.hasMoreElements()) { | ||
vector.add(enumeration.nextElement()); }} | ||
return vector.elements(); } | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really intend to modify JFR's master branch with using JDK11 as default? Or maybe we don't care because packagers are always expected to pass this
ARG
?