Skip to content

Commit dd66fee

Browse files
authored
Add JDK Api extractor tool to help with entitlement reviews (#132920)
This tool scans the JDK on which it runs to extract its public accessible API. That is: - public and protected non-final methods (including constructors) of public, exported classes - internal implementations (overwrites) of above The output of this tool is meant to be diffed against the output for another JDK version to identify changes that need to be reviewed for entitlements. Using --deprecations-only deprecations can we viewed. Relates to ES-12408, ES-12407
1 parent 70eb3db commit dd66fee

File tree

8 files changed

+408
-6
lines changed

8 files changed

+408
-6
lines changed

libs/entitlement/tools/common/src/main/java/org/elasticsearch/entitlement/tools/Utils.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,22 @@
2424

2525
public class Utils {
2626

27+
// TODO Currently ServerProcessBuilder is using --add-modules=ALL-MODULE-PATH, should this rather
28+
// reflect below excludes (except for java.desktop which requires a special handling)?
29+
// internal and incubator modules are also excluded
2730
private static final Set<String> EXCLUDED_MODULES = Set.of(
2831
"java.desktop",
2932
"jdk.jartool",
3033
"jdk.jdi",
3134
"java.security.jgss",
32-
"jdk.jshell"
35+
"jdk.jshell",
36+
"jdk.jcmd",
37+
"jdk.hotspot.agent",
38+
"jdk.jfr",
39+
"jdk.javadoc",
40+
// "jdk.jpackage", // Do we want to include this?
41+
// "jdk.jlink", // Do we want to include this?
42+
"jdk.localedata" // noise, change here are not interesting
3343
);
3444

3545
private static Map<String, Set<String>> findModuleExports(FileSystem fs) throws IOException {
@@ -70,7 +80,9 @@ public static void walkJdkModules(JdkModuleConsumer c) throws IOException {
7080

7181
for (var kv : modules.entrySet()) {
7282
var moduleName = kv.getKey();
73-
if (Utils.EXCLUDED_MODULES.contains(moduleName) == false) {
83+
if (Utils.EXCLUDED_MODULES.contains(moduleName) == false
84+
&& moduleName.contains(".internal.") == false
85+
&& moduleName.contains(".incubator.") == false) {
7486
var thisModuleExports = moduleExports.get(moduleName);
7587
c.accept(moduleName, kv.getValue(), thisModuleExports);
7688
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
This tool scans the JDK on which it is running to extract its public accessible API.
2+
That is:
3+
- public methods (including constructors) of public, exported classes as well as protected methods of these if not final.
4+
- internal implementations (overwrites) of above.
5+
6+
The output of this tool is meant to be diffed against the output for another JDK
7+
version to identify changes that need to be reviewed for entitlements.
8+
9+
Usage example:
10+
```bash
11+
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=24 --args="api-jdk24.tsv"
12+
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=25 --args="api-jdk25.tsv"
13+
diff libs/entitlement/tools/jdk-api-extractor/api-jdk24.tsv libs/entitlement/tools/jdk-api-extractor/api-jdk25.tsv
14+
```
15+
16+
To review the diff of deprecations (by means of `@Deprecated`), use `--deprecations-only` as 2nd argument.
17+
18+
```bash
19+
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=24 --args="deprecations-jdk24.tsv --deprecations-only"
20+
```
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import org.elasticsearch.gradle.OS
2+
3+
plugins {
4+
id 'application'
5+
}
6+
7+
apply plugin: 'elasticsearch.build'
8+
9+
tasks.named("dependencyLicenses").configure {
10+
mapping from: /asm-.*/, to: 'asm'
11+
}
12+
13+
group = 'org.elasticsearch.entitlement.tools'
14+
15+
ext {
16+
javaMainClass = "org.elasticsearch.entitlement.tools.jdkapi.JdkApiExtractor"
17+
}
18+
19+
application {
20+
mainClass.set(javaMainClass)
21+
applicationDefaultJvmArgs = [
22+
'--add-exports', 'java.base/sun.security.util=ALL-UNNAMED',
23+
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
24+
'--add-opens', 'java.base/java.net=ALL-UNNAMED',
25+
'--add-opens', 'java.base/java.net.spi=ALL-UNNAMED',
26+
'--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED',
27+
'--add-opens', 'java.base/javax.crypto=ALL-UNNAMED',
28+
'--add-opens', 'java.base/javax.security.auth=ALL-UNNAMED',
29+
'--add-opens', 'java.base/jdk.internal.logger=ALL-UNNAMED',
30+
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
31+
'--add-opens', 'jdk.management.jfr/jdk.management.jfr=ALL-UNNAMED',
32+
'--add-opens', 'java.logging/java.util.logging=ALL-UNNAMED',
33+
'--add-opens', 'java.logging/sun.util.logging.internal=ALL-UNNAMED',
34+
'--add-opens', 'java.naming/javax.naming.ldap.spi=ALL-UNNAMED',
35+
'--add-opens', 'java.rmi/sun.rmi.runtime=ALL-UNNAMED',
36+
'--add-opens', 'jdk.dynalink/jdk.dynalink=ALL-UNNAMED',
37+
'--add-opens', 'jdk.dynalink/jdk.dynalink.linker=ALL-UNNAMED',
38+
'--add-opens', 'java.desktop/sun.awt=ALL-UNNAMED',
39+
'--add-opens', 'java.sql.rowset/javax.sql.rowset.spi=ALL-UNNAMED',
40+
'--add-opens', 'java.sql/java.sql=ALL-UNNAMED',
41+
'--add-opens', 'java.xml.crypto/com.sun.org.apache.xml.internal.security.utils=ALL-UNNAMED'
42+
]
43+
}
44+
45+
tasks.named("run").configure {
46+
executable = "${buildParams.runtimeJavaHome.get()}/bin/java" + (OS.current() == OS.WINDOWS ? '.exe' : '')
47+
}
48+
49+
repositories {
50+
mavenCentral()
51+
}
52+
53+
dependencies {
54+
compileOnly(project(':libs:core'))
55+
implementation 'org.ow2.asm:asm:9.8'
56+
implementation 'org.ow2.asm:asm-util:9.8'
57+
implementation(project(':libs:entitlement:tools:common'))
58+
}
59+
60+
tasks.named('forbiddenApisMain').configure {
61+
replaceSignatureFiles 'jdk-signatures'
62+
}
63+
64+
tasks.named("thirdPartyAudit").configure {
65+
ignoreMissingClasses()
66+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright (c) 2012 France Télécom
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions
6+
are met:
7+
1. Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright
10+
notice, this list of conditions and the following disclaimer in the
11+
documentation and/or other materials provided with the distribution.
12+
3. Neither the name of the copyright holders nor the names of its
13+
contributors may be used to endorse or promote products derived from
14+
this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)