Set up Eclipse to work with Java 9 and later
To create .classpath with java 9, run: $ tools/eclipse/project.py --java 9 Start Eclipse, and follow the instructions provided in dev-eclipse.txt to switch to Java 9 or later. To run gerrit from Eclipse, the system classpath is cast to URLClassLoader to retrieve the needed JARs. In Java 9 system classpath cannot be cast to URLClassLoader. To rectify, extract the classpath from Bazel. Change-Id: Ie341cd4dfee5520f689fc50f34aa5395b74b5e7d
This commit is contained in:
parent
f51cf2323b
commit
8aae31c376
@ -3,7 +3,7 @@
|
|||||||
This document is about configuring Gerrit Code Review into an
|
This document is about configuring Gerrit Code Review into an
|
||||||
Eclipse workspace for development and debugging with GWT.
|
Eclipse workspace for development and debugging with GWT.
|
||||||
|
|
||||||
Java 6 or later SDK is also required to run GWT's compiler and
|
Java 8 or later SDK is also required to run GWT's compiler and
|
||||||
runtime debugging environment.
|
runtime debugging environment.
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +49,19 @@ the same way you would when
|
|||||||
link:dev-build-plugins.html#_bundle_custom_plugin_in_release_war[bundling in release.war]
|
link:dev-build-plugins.html#_bundle_custom_plugin_in_release_war[bundling in release.war]
|
||||||
and run `tools/eclipse/project.py`.
|
and run `tools/eclipse/project.py`.
|
||||||
|
|
||||||
|
[[Newer Java versions]]
|
||||||
|
|
||||||
|
Java 9 and later are supported, but some adjustments must be done, because
|
||||||
|
Java 8 is still the default:
|
||||||
|
|
||||||
|
* Add JRE, e.g.: directory: /usr/lib64/jvm/java-9-openjdk, name: java-9-openjdk-9
|
||||||
|
* Change execution environemnt for gerrit project to: JavaSE-9 (java-9-openjdk-9)
|
||||||
|
* Check that compiler compliance level in gerrit project is set to: 9
|
||||||
|
* Add this parameter to VM argument for gerrit_daemin launcher:
|
||||||
|
----
|
||||||
|
--add-modules java.activation \
|
||||||
|
--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
|
||||||
|
----
|
||||||
|
|
||||||
[[Formatting]]
|
[[Formatting]]
|
||||||
== Code Formatter Settings
|
== Code Formatter Settings
|
||||||
|
@ -23,14 +23,15 @@ import com.google.common.flogger.FluentLogger;
|
|||||||
import com.google.common.html.HtmlEscapers;
|
import com.google.common.html.HtmlEscapers;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.gerrit.common.TimeUtil;
|
import com.google.gerrit.common.TimeUtil;
|
||||||
|
import com.google.gerrit.launcher.GerritLauncher;
|
||||||
import com.google.gerrit.util.http.CacheHeaders;
|
import com.google.gerrit.util.http.CacheHeaders;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NoSuchFileException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.eclipse.jgit.util.RawParseUtils;
|
import org.eclipse.jgit.util.RawParseUtils;
|
||||||
@ -122,20 +123,19 @@ public class BazelBuild {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Properties loadBuildProperties(Path propPath) throws IOException {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
try (InputStream in = Files.newInputStream(propPath)) {
|
|
||||||
properties.load(in);
|
|
||||||
} catch (NoSuchFileException e) {
|
|
||||||
// Ignore; will be run from PATH, with a descriptive error if it fails.
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessBuilder newBuildProcess(Label label) throws IOException {
|
private ProcessBuilder newBuildProcess(Label label) throws IOException {
|
||||||
Properties properties = loadBuildProperties(sourceRoot.resolve(".bazel_path"));
|
Properties properties = GerritLauncher.loadBuildProperties(sourceRoot.resolve(".bazel_path"));
|
||||||
String bazel = firstNonNull(properties.getProperty("bazel"), "bazel");
|
String bazel = firstNonNull(properties.getProperty("bazel"), "bazel");
|
||||||
ProcessBuilder proc = new ProcessBuilder(bazel, "build", label.fullName());
|
List<String> cmd = new ArrayList<>();
|
||||||
|
cmd.add(bazel);
|
||||||
|
cmd.add("build");
|
||||||
|
if (GerritLauncher.isJdk9OrLater()) {
|
||||||
|
String v = GerritLauncher.getJdkVersionPostJdk8();
|
||||||
|
cmd.add("--host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java" + v);
|
||||||
|
cmd.add("--java_toolchain=@bazel_tools//tools/jdk:toolchain_java" + v);
|
||||||
|
}
|
||||||
|
cmd.add(label.fullName());
|
||||||
|
ProcessBuilder proc = new ProcessBuilder(cmd);
|
||||||
if (properties.containsKey("PATH")) {
|
if (properties.containsKey("PATH")) {
|
||||||
proc.environment().put("PATH", properties.getProperty("PATH"));
|
proc.environment().put("PATH", properties.getProperty("PATH"));
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import java.net.URLClassLoader;
|
|||||||
import java.nio.file.FileSystem;
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.security.CodeSource;
|
import java.security.CodeSource;
|
||||||
@ -44,6 +45,7 @@ import java.util.Enumeration;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -644,6 +646,25 @@ public final class GerritLauncher {
|
|||||||
return resolveInSourceRoot("eclipse-out");
|
return resolveInSourceRoot("eclipse-out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isJdk9OrLater() {
|
||||||
|
return Double.parseDouble(System.getProperty("java.class.version")) >= 53.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getJdkVersionPostJdk8() {
|
||||||
|
// 9.0.4 => 9
|
||||||
|
return System.getProperty("java.version").substring(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Properties loadBuildProperties(Path propPath) throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try (InputStream in = Files.newInputStream(propPath)) {
|
||||||
|
properties.load(in);
|
||||||
|
} catch (NoSuchFileException e) {
|
||||||
|
// Ignore; will be run from PATH, with a descriptive error if it fails.
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
static final String SOURCE_ROOT_RESOURCE = "/com/google/gerrit/launcher/workspace-root.txt";
|
static final String SOURCE_ROOT_RESOURCE = "/com/google/gerrit/launcher/workspace-root.txt";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -708,23 +729,47 @@ public final class GerritLauncher {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ClassLoader useDevClasspath() throws MalformedURLException, FileNotFoundException {
|
private static ClassLoader useDevClasspath() throws IOException {
|
||||||
Path out = getDeveloperEclipseOut();
|
Path out = getDeveloperEclipseOut();
|
||||||
List<URL> dirs = new ArrayList<>();
|
List<URL> dirs = new ArrayList<>();
|
||||||
dirs.add(out.resolve("classes").toUri().toURL());
|
dirs.add(out.resolve("classes").toUri().toURL());
|
||||||
ClassLoader cl = GerritLauncher.class.getClassLoader();
|
ClassLoader cl = GerritLauncher.class.getClassLoader();
|
||||||
|
|
||||||
|
if (isJdk9OrLater()) {
|
||||||
|
Path rootPath = resolveInSourceRoot(".").normalize();
|
||||||
|
|
||||||
|
Properties properties = loadBuildProperties(rootPath.resolve(".bazel_path"));
|
||||||
|
Path outputBase = Paths.get(properties.getProperty("output_base"));
|
||||||
|
|
||||||
|
Path runtimeClasspath =
|
||||||
|
rootPath.resolve("bazel-bin/tools/eclipse/main_classpath_collect.runtime_classpath");
|
||||||
|
for (String f : Files.readAllLines(runtimeClasspath, UTF_8)) {
|
||||||
|
URL url;
|
||||||
|
if (f.startsWith("external")) {
|
||||||
|
url = outputBase.resolve(f).toUri().toURL();
|
||||||
|
} else {
|
||||||
|
url = rootPath.resolve(f).toUri().toURL();
|
||||||
|
}
|
||||||
|
if (includeJar(url)) {
|
||||||
|
dirs.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (URL u : ((URLClassLoader) cl).getURLs()) {
|
for (URL u : ((URLClassLoader) cl).getURLs()) {
|
||||||
if (includeJar(u)) {
|
if (includeJar(u)) {
|
||||||
dirs.add(u);
|
dirs.add(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return URLClassLoader.newInstance(
|
return URLClassLoader.newInstance(
|
||||||
dirs.toArray(new URL[dirs.size()]), ClassLoader.getSystemClassLoader().getParent());
|
dirs.toArray(new URL[dirs.size()]), ClassLoader.getSystemClassLoader().getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean includeJar(URL u) {
|
private static boolean includeJar(URL u) {
|
||||||
String path = u.getPath();
|
String path = u.getPath();
|
||||||
return path.endsWith(".jar") && !path.endsWith("-src.jar");
|
return path.endsWith(".jar")
|
||||||
|
&& !path.endsWith("-src.jar")
|
||||||
|
&& !path.contains("/com/google/gerrit");
|
||||||
}
|
}
|
||||||
|
|
||||||
private GerritLauncher() {}
|
private GerritLauncher() {}
|
||||||
|
@ -32,7 +32,7 @@ AUTO = '//lib/auto:auto-value'
|
|||||||
JRE = '/'.join([
|
JRE = '/'.join([
|
||||||
'org.eclipse.jdt.launching.JRE_CONTAINER',
|
'org.eclipse.jdt.launching.JRE_CONTAINER',
|
||||||
'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
|
'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
|
||||||
'JavaSE-1.8',
|
'JavaSE-9',
|
||||||
])
|
])
|
||||||
# Map of targets to corresponding classpath collector rules
|
# Map of targets to corresponding classpath collector rules
|
||||||
cp_targets = {
|
cp_targets = {
|
||||||
@ -52,10 +52,12 @@ opts.add_option('--name', help='name of the generated project',
|
|||||||
action='store', default='gerrit', dest='project_name')
|
action='store', default='gerrit', dest='project_name')
|
||||||
opts.add_option('-b', '--batch', action='store_true',
|
opts.add_option('-b', '--batch', action='store_true',
|
||||||
dest='batch', help='Bazel batch option')
|
dest='batch', help='Bazel batch option')
|
||||||
|
opts.add_option('-j', '--java', action='store',
|
||||||
|
dest='java', help='Post Java 8 support (9|10|11|...)')
|
||||||
args, _ = opts.parse_args()
|
args, _ = opts.parse_args()
|
||||||
|
|
||||||
batch_option = '--batch' if args.batch else None
|
batch_option = '--batch' if args.batch else None
|
||||||
|
custom_java = args.java
|
||||||
|
|
||||||
def _build_bazel_cmd(*args):
|
def _build_bazel_cmd(*args):
|
||||||
cmd = ['bazel']
|
cmd = ['bazel']
|
||||||
@ -63,6 +65,9 @@ def _build_bazel_cmd(*args):
|
|||||||
cmd.append('--batch')
|
cmd.append('--batch')
|
||||||
for arg in args:
|
for arg in args:
|
||||||
cmd.append(arg)
|
cmd.append(arg)
|
||||||
|
if custom_java:
|
||||||
|
cmd.append('--host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java)
|
||||||
|
cmd.append('--java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
@ -70,9 +75,10 @@ def retrieve_ext_location():
|
|||||||
return check_output(_build_bazel_cmd('info', 'output_base')).strip()
|
return check_output(_build_bazel_cmd('info', 'output_base')).strip()
|
||||||
|
|
||||||
|
|
||||||
def gen_bazel_path():
|
def gen_bazel_path(ext_location):
|
||||||
bazel = check_output(['which', 'bazel']).strip().decode('UTF-8')
|
bazel = check_output(['which', 'bazel']).strip().decode('UTF-8')
|
||||||
with open(path.join(ROOT, ".bazel_path"), 'w') as fd:
|
with open(path.join(ROOT, ".bazel_path"), 'w') as fd:
|
||||||
|
fd.write("output_base=%s\n" % ext_location)
|
||||||
fd.write("bazel=%s\n" % bazel)
|
fd.write("bazel=%s\n" % bazel)
|
||||||
fd.write("PATH=%s\n" % environ["PATH"])
|
fd.write("PATH=%s\n" % environ["PATH"])
|
||||||
|
|
||||||
@ -301,7 +307,7 @@ try:
|
|||||||
gen_project(args.project_name)
|
gen_project(args.project_name)
|
||||||
gen_classpath(ext_location)
|
gen_classpath(ext_location)
|
||||||
gen_factorypath(ext_location)
|
gen_factorypath(ext_location)
|
||||||
gen_bazel_path()
|
gen_bazel_path(ext_location)
|
||||||
|
|
||||||
# TODO(davido): Remove this when GWT gone
|
# TODO(davido): Remove this when GWT gone
|
||||||
gwt_working_dir = ".gwt_work_dir"
|
gwt_working_dir = ".gwt_work_dir"
|
||||||
|
Loading…
Reference in New Issue
Block a user