Skip to content

Commit c0d043e

Browse files
Support platform specific extension (#2183)
* Support platform specific extension Signed-off-by: Jinbo Wang <[email protected]>
1 parent 530a3f6 commit c0d043e

File tree

11 files changed

+341
-102
lines changed

11 files changed

+341
-102
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ node_modules
77
undefined
88
target
99
dist
10+
jre
1011
bin/
1112
.settings
1213
.classpath

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,26 @@
110110
"outFiles": ["${workspaceRoot}/out/**/*.js"],
111111
"preLaunchTask": "prepareLightweightTest",
112112
"postDebugTask": "cleanTestFolder"
113+
},
114+
{
115+
"args": [
116+
"${input:gulpTask}"
117+
],
118+
"name": "Launch Gulp Task",
119+
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
120+
"request": "launch",
121+
"skipFiles": [
122+
"<node_internals>/**"
123+
],
124+
"type": "pwa-node"
125+
}
126+
],
127+
"inputs": [
128+
{
129+
"id": "gulpTask",
130+
"type": "promptString",
131+
"description": "Name of the Gulp task to execute",
132+
"default": "download_jre"
113133
}
114134
]
115135
}

.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ gulpfile.js
2222
Jenkinsfile
2323
tslint.json
2424
webpack.config.js
25+
.DS_Store

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ The following will be a start to finish guide to get the entire language server
5454
```bash
5555
$ npm install
5656
```
57+
5. (**\*Optional**) Build a platform specific JRE:
58+
59+
```bash
60+
$ npx gulp download_jre
61+
```
62+
You can also use the options `--target` and `--javaVersion` to build the specified JRE version for the specified target architecture.
5763

5864
#
5965

Jenkinsfile

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ node('rhel8'){
4646

4747
stage "Package vscode-java"
4848
def packageJson = readJSON file: 'package.json'
49-
sh "vsce package -o java-${packageJson.version}-${env.BUILD_NUMBER}.vsix"
49+
env.EXTENSION_VERSION = "${packageJson.version}"
50+
sh "vsce package -o java-${env.EXTENSION_VERSION}-${env.BUILD_NUMBER}.vsix"
5051

5152
stage 'Test vscode-java for staging'
5253
wrap([$class: 'Xvnc']) {
@@ -55,10 +56,28 @@ node('rhel8'){
5556
sh "npm test --silent"
5657
}
5758

58-
stage 'Upload vscode-java to staging'
5959
def vsix = findFiles(glob: '**.vsix')
60-
sh "rsync -Pzrlt --rsh=ssh --protocol=28 ${vsix[0].path} ${UPLOAD_LOCATION}/jdt.ls/staging"
61-
stash name:'vsix', includes:files[0].path
60+
stash name:'vsix', includes:vsix[0].path
61+
62+
// Package platform specific versions
63+
stage "Package platform specific vscode-java"
64+
def platforms = ["win32-x64", "linux-x64", "linux-arm64", "darwin-x64", "darwin-arm64"]
65+
def embeddedJRE = 17
66+
for(platform in platforms){
67+
sh "npx gulp download_jre --target ${platform} --javaVersion ${embeddedJRE}"
68+
sh "vsce package --target ${platform} -o java-${platform}-${env.EXTENSION_VERSION}-${env.BUILD_NUMBER}.vsix"
69+
}
70+
stash name:'platformVsix', includes:'java-win32-*.vsix,java-linux-*.vsix,java-darwin-*.vsix'
71+
72+
stage 'Upload vscode-java to staging'
73+
def artifacts = findFiles(glob: '**.vsix')
74+
def artifactDir = "java-${env.EXTENSION_VERSION}-${env.BUILD_NUMBER}"
75+
sh "mkdir ${artifactDir}"
76+
sh "mv *.vsix ${artifactDir}"
77+
78+
for(artifact in artifacts){
79+
sh "rsync -Pzrlt --rsh=ssh --protocol=28 --relative ${artifactDir}/${artifact.path} ${UPLOAD_LOCATION}/jdt.ls/staging"
80+
}
6281
}
6382

6483
node('rhel8'){
@@ -67,24 +86,40 @@ node('rhel8'){
6786
input message:'Approve deployment?', submitter: 'fbricon,rgrunber'
6887
}
6988

70-
stage "Publish to Marketplaces"
89+
stage "Publish to Open-vsx Marketplace"
7190
unstash 'vsix'
7291
def vsix = findFiles(glob: '**.vsix')
73-
// VS Code Marketplace
74-
withCredentials([[$class: 'StringBinding', credentialsId: 'vscode_java_marketplace', variable: 'TOKEN']]) {
75-
sh 'vsce publish -p ${TOKEN} --packagePath' + " ${vsix[0].path}"
76-
}
77-
7892
// Open-vsx Marketplace
7993
sh "npm install -g ovsx"
8094
withCredentials([[$class: 'StringBinding', credentialsId: 'open-vsx-access-token', variable: 'OVSX_TOKEN']]) {
8195
sh 'ovsx publish -p ${OVSX_TOKEN}' + " ${vsix[0].path}"
8296
}
8397

84-
archive includes:"**.vsix"
98+
stage "Publish to VS Code Marketplace"
99+
// VS Code Marketplace
100+
withCredentials([[$class: 'StringBinding', credentialsId: 'vscode_java_marketplace', variable: 'TOKEN']]) {
101+
// Publish a generic version
102+
sh 'vsce publish -p ${TOKEN} --target win32-ia32 win32-arm64 linux-armhf alpine-x64 alpine-arm64'
103+
104+
// Publish platform specific versions
105+
unstash 'platformVsix'
106+
def platformVsixes = findFiles(glob: '**.vsix', excludes: vsix[0].path)
107+
for(platformVsix in platformVsixes){
108+
sh 'vsce publish -p ${TOKEN}' + " --packagePath ${platformVsix.path}"
109+
}
110+
}
85111

86112
stage "Publish to http://download.jboss.org/jbosstools/static/jdt.ls/stable/"
113+
def artifacts = findFiles(glob: '**.vsix')
114+
def artifactDir = "java-${env.EXTENSION_VERSION}"
115+
sh "mkdir ${artifactDir}"
116+
sh "mv *.vsix ${artifactDir}"
117+
118+
archive includes:"${artifactDir}/**/*.*"
119+
87120
// copy this stable build to Akamai-mirrored /static/ URL, so staging can be cleaned out more easily
88-
sh "rsync -Pzrlt --rsh=ssh --protocol=28 ${vsix[0].path} ${UPLOAD_LOCATION}/static/jdt.ls/stable/"
121+
for(artifact in artifacts){
122+
sh "rsync -Pzrlt --rsh=ssh --protocol=28 --relative ${artifactDir}/${artifact.path} ${UPLOAD_LOCATION}/static/jdt.ls/stable/"
123+
}
89124
}// if publishToMarketPlace
90125
}

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,16 @@ See the [changelog](CHANGELOG.md) for the latest release. You might also find us
5454
Setting the JDK
5555
===============
5656
## Java Tooling JDK
57-
This JDK will be used to launch the Java Language Server. And by default, will also be used to compile your projects.
57+
Now that Java extension will publish platform specific versions, it will embed a JRE for supported platforms such as `win32-x64`, `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`. The embedded JRE is used to launch the Language Server for Java. Users are only responsible for configuring [Project JDKs](#project-jdks) to compile your Java projects.
5858

59-
The path to the Java Development Kit can be specified by the `java.home` setting in VS Code settings (workspace/user settings). If not specified, it is searched in the following order until a JDK meets current minimum requirement.
59+
The following part is only kept for the universal version without embedded JRE.
6060

61-
- the `JDK_HOME` environment variable
62-
- the `JAVA_HOME` environment variable
63-
- on the current system path
61+
>The tooling JDK will be used to launch the Language Server for Java. And by default, will also be used to compile your projects.\
62+
\
63+
The path to the Java Development Kit can be specified by the `java.home` setting in VS Code settings (workspace/user settings). If not specified, it is searched in the following order until a JDK meets current minimum requirement.
64+
>- the `JDK_HOME` environment variable
65+
>- the `JAVA_HOME` environment variable
66+
>- on the current system path
6467
6568
## Project JDKs
6669
If you need to compile your projects against a different JDK version, it's recommended you configure the `java.configuration.runtimes` property in your user settings, eg:
@@ -107,7 +110,7 @@ Supported VS Code settings
107110
==========================
108111
The following settings are supported:
109112

110-
* `java.home` : Absolute path to JDK home folder used to launch the Java Language Server. Requires VS Code restart.
113+
* `java.home` : **Deprecated, only used for universal version without embedded JRE.** Absolute path to JDK home folder used to launch the Java Language Server. Requires VS Code restart.
111114
* `java.jdt.ls.vmargs` : Extra VM arguments used to launch the Java Language Server. Requires VS Code restart.
112115
* `java.errors.incompleteClasspath.severity` : Specifies the severity of the message when the classpath is incomplete for a Java file. Supported values are `ignore`, `info`, `warning`, `error`.
113116
* `java.trace.server` : Traces the communication between VS Code and the Java language server.

gulpfile.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,119 @@ const gulp = require('gulp');
33
const cp = require('child_process');
44
const decompress = require('gulp-decompress');
55
const download = require('gulp-download');
6+
const request = require('request');
67
const glob = require('glob');
78
const fse = require('fs-extra');
89
const path = require('path');
10+
const url = require("url");
11+
const argv = require('minimist')(process.argv.slice(2));
912
const server_dir = '../eclipse.jdt.ls';
1013
const originalTestFolder = path.join(__dirname, 'test', 'resources', 'projects', 'maven', 'salut');
1114
const tempTestFolder = path.join(__dirname, 'test-temp');
1215
const testSettings = path.join(tempTestFolder, '.vscode', 'settings.json');
1316
//...
1417

18+
gulp.task('clean_jre', function(done) {
19+
if (fse.existsSync('./jre')) {
20+
fse.removeSync('./jre');
21+
}
22+
23+
done();
24+
});
25+
26+
// Pls update the latest JRE if a new JDK is announced.
27+
const LATEST_JRE = 17;
28+
29+
/**
30+
* Usage:
31+
* npx gulp download_jre // Download the latest JRE for the platform of the current running machine.
32+
* npx gulp download_jre --target darwin-x64 --javaVersion 17 // Download the specified JRE for the specified platform.
33+
*
34+
* Supported platforms:
35+
* win32-x64,
36+
* linux-x64,
37+
* linux-arm64,
38+
* darwin-x64,
39+
* darwin-arm64
40+
*/
41+
gulp.task('download_jre', async function(done) {
42+
if (fse.existsSync('./jre')) {
43+
fse.removeSync('./jre');
44+
}
45+
46+
const platformMapping = {
47+
"linux-arm64": "linux-aarch64",
48+
"linux-x64": "linux-x86_64",
49+
"darwin-arm64": "macosx-aarch64",
50+
"darwin-x64": "macosx-x86_64",
51+
"win32-x64": "win32-x86_64"
52+
}
53+
54+
const targetPlatform = argv.target || process.platform + "-" + process.arch;
55+
if (targetPlatform && Object.keys(platformMapping).includes(targetPlatform)) {
56+
const javaVersion = (!argv.javaVersion || argv.javaVersion === "latest") ? LATEST_JRE : argv.javaVersion;
57+
console.log("Downloading justj JRE " + javaVersion + " for the platform " + targetPlatform) + "...";
58+
59+
const manifestUrl = `https://download.eclipse.org/justj/jres/${javaVersion}/downloads/latest/justj.manifest`;
60+
// Download justj.manifest file
61+
const manifest = await new Promise(function(resolve, reject) {
62+
request.get(manifestUrl, function(err, response, body) {
63+
if(err || response.statusCode >= 400) {
64+
reject(err || `${response.statusCode} returned from ${manifestUrl}`);
65+
} else {
66+
resolve(String(body));
67+
}
68+
});
69+
});
70+
71+
if (!manifest) {
72+
done(new Error(`Failed to download justj.manifest, please check if the link ${manifestUrl} is valid.`))
73+
return;
74+
}
75+
76+
/**
77+
* Here are the contents for a sample justj.manifest file:
78+
* ../20211012_0921/org.eclipse.justj.openjdk.hotspot.jre.full.stripped-17-linux-aarch64.tar.gz
79+
* ../20211012_0921/org.eclipse.justj.openjdk.hotspot.jre.full.stripped-17-linux-x86_64.tar.gz
80+
* ../20211012_0921/org.eclipse.justj.openjdk.hotspot.jre.full.stripped-17-macosx-aarch64.tar.gz
81+
* ../20211012_0921/org.eclipse.justj.openjdk.hotspot.jre.full.stripped-17-macosx-x86_64.tar.gz
82+
* ../20211012_0921/org.eclipse.justj.openjdk.hotspot.jre.full.stripped-17-win32-x86_64.tar.gz
83+
*/
84+
const javaPlatform = platformMapping[targetPlatform];
85+
const list = manifest.split(/\r?\n/);
86+
const jreIdentifier = list.find((value) => {
87+
return value.indexOf("org.eclipse.justj.openjdk.hotspot.jre.full.stripped") >= 0 && value.indexOf(javaPlatform) >= 0;
88+
});
89+
90+
if (!jreIdentifier) {
91+
done(new Error(`justj doesn't support the jre ${javaVersion} for the platform ${javaPlatform} (${targetPlatform}), please refer to the link ${manifestUrl} for the supported platforms.`));
92+
return;
93+
}
94+
95+
const jreDownloadUrl = `https://download.eclipse.org/justj/jres/${javaVersion}/downloads/latest/${jreIdentifier}`;
96+
const parsedDownloadUrl = url.parse(jreDownloadUrl);
97+
const jreFileName = path.basename(parsedDownloadUrl.pathname)
98+
.replace(/[\.7z|\.bz2|\.gz|\.rar|\.tar|\.zip|\.xz]*$/, "");
99+
const idx = jreFileName.indexOf('-');
100+
const jreVersionLabel = idx >= 0 ? jreFileName.substring(idx + 1) : jreFileName;
101+
// Download justj JRE.
102+
await new Promise(function(resolve, reject) {
103+
download(jreDownloadUrl)
104+
.on('error', reject)
105+
.pipe(decompress({strip: 0}))
106+
.pipe(gulp.dest('./jre/' + jreVersionLabel))
107+
.on('end', resolve);
108+
});
109+
} else {
110+
console.log("[Error] download_jre failed, please specify a valid target platform via --target argument. Here are the supported platform list:");
111+
for (const platform of Object.keys(platformMapping)) {
112+
console.log(platform);
113+
}
114+
}
115+
116+
done();
117+
});
118+
15119
gulp.task('download_server', function(done) {
16120
fse.removeSync('./server');
17121
download("http://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz")

0 commit comments

Comments
 (0)