Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,22 @@

public class Utils {

// TODO Currently ServerProcessBuilder is using --add-modules=ALL-MODULE-PATH, should this rather
// reflect below excludes (except for java.desktop which requires a special handling)?
// internal and incubator modules are also excluded
private static final Set<String> EXCLUDED_MODULES = Set.of(
"java.desktop",
"jdk.jartool",
"jdk.jdi",
"java.security.jgss",
"jdk.jshell"
"jdk.jshell",
"jdk.jcmd",
"jdk.hotspot.agent",
"jdk.jfr",
"jdk.javadoc",
// "jdk.jpackage", // Do we want to include this?
// "jdk.jlink", // Do we want to include this?
"jdk.localedata" // noise, change here are not interesting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe not interesting for entitlements, though note that we see test failures often because of localedata changes, so maybe having something similar as a comparison is useful for jdk upgrades?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting point, though not sure how actionable the changes are. but worth investigating. I'll leave this as a point in the future automation jira

);

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

for (var kv : modules.entrySet()) {
var moduleName = kv.getKey();
if (Utils.EXCLUDED_MODULES.contains(moduleName) == false) {
if (Utils.EXCLUDED_MODULES.contains(moduleName) == false
&& moduleName.contains(".internal.") == false
&& moduleName.contains(".incubator.") == false) {
var thisModuleExports = moduleExports.get(moduleName);
c.accept(moduleName, kv.getValue(), thisModuleExports);
}
Expand Down
20 changes: 20 additions & 0 deletions libs/entitlement/tools/jdk-api-extractor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
This tool scans the JDK on which it is running to extract its public accessible API.
That is:
- public methods (including constructors) of public, exported classes as well as protected methods of these if not final.
- 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.

Usage example:
```bash
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=24 --args="api-jdk24.tsv"
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=25 --args="api-jdk25.tsv"
diff libs/entitlement/tools/jdk-api-extractor/api-jdk24.tsv libs/entitlement/tools/jdk-api-extractor/api-jdk25.tsv
```

To review the diff of deprecations (by means of `@Deprecated`), use `--deprecations-only` as 2nd argument.

```bash
./gradlew :libs:entitlement:tools:jdk-api-extractor:run -Druntime.java=24 --args="deprecations-jdk24.tsv --deprecations-only"
```
66 changes: 66 additions & 0 deletions libs/entitlement/tools/jdk-api-extractor/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import org.elasticsearch.gradle.OS

plugins {
id 'application'
}

apply plugin: 'elasticsearch.build'

tasks.named("dependencyLicenses").configure {
mapping from: /asm-.*/, to: 'asm'
}

group = 'org.elasticsearch.entitlement.tools'

ext {
javaMainClass = "org.elasticsearch.entitlement.tools.jdkapi.JdkApiExtractor"
}

application {
mainClass.set(javaMainClass)
applicationDefaultJvmArgs = [
'--add-exports', 'java.base/sun.security.util=ALL-UNNAMED',
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about potentially new packages we don't know about? Could we scan the jdk itself for packages (eg at the filesystem level by opening up the archives that contain modules)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the JDK on which you are running the tool have new packages, it will try to access them and it will break (so you'll need to come back here and add them to the list).
What you are suggesting is definitely possible though; packages will just be directories inside the modules we are scanning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right 👍 I'll note it as future improvement in the automatic task 👍

'--add-opens', 'java.base/java.net=ALL-UNNAMED',
'--add-opens', 'java.base/java.net.spi=ALL-UNNAMED',
'--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED',
'--add-opens', 'java.base/javax.crypto=ALL-UNNAMED',
'--add-opens', 'java.base/javax.security.auth=ALL-UNNAMED',
'--add-opens', 'java.base/jdk.internal.logger=ALL-UNNAMED',
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
'--add-opens', 'jdk.management.jfr/jdk.management.jfr=ALL-UNNAMED',
'--add-opens', 'java.logging/java.util.logging=ALL-UNNAMED',
'--add-opens', 'java.logging/sun.util.logging.internal=ALL-UNNAMED',
'--add-opens', 'java.naming/javax.naming.ldap.spi=ALL-UNNAMED',
'--add-opens', 'java.rmi/sun.rmi.runtime=ALL-UNNAMED',
'--add-opens', 'jdk.dynalink/jdk.dynalink=ALL-UNNAMED',
'--add-opens', 'jdk.dynalink/jdk.dynalink.linker=ALL-UNNAMED',
'--add-opens', 'java.desktop/sun.awt=ALL-UNNAMED',
'--add-opens', 'java.sql.rowset/javax.sql.rowset.spi=ALL-UNNAMED',
'--add-opens', 'java.sql/java.sql=ALL-UNNAMED',
'--add-opens', 'java.xml.crypto/com.sun.org.apache.xml.internal.security.utils=ALL-UNNAMED'
]
}

tasks.named("run").configure {
executable = "${buildParams.runtimeJavaHome.get()}/bin/java" + (OS.current() == OS.WINDOWS ? '.exe' : '')
}

repositories {
mavenCentral()
}

dependencies {
compileOnly(project(':libs:core'))
implementation 'org.ow2.asm:asm:9.8'
implementation 'org.ow2.asm:asm-util:9.8'
implementation(project(':libs:entitlement:tools:common'))
}

tasks.named('forbiddenApisMain').configure {
replaceSignatureFiles 'jdk-signatures'
}

tasks.named("thirdPartyAudit").configure {
ignoreMissingClasses()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright (c) 2012 France Télécom
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading