diff --git a/libs/entitlement/tools/common/src/main/java/org/elasticsearch/entitlement/tools/ExternalAccess.java b/libs/entitlement/tools/common/src/main/java/org/elasticsearch/entitlement/tools/ExternalAccess.java index cd049a91fa4da..e36f760605cba 100644 --- a/libs/entitlement/tools/common/src/main/java/org/elasticsearch/entitlement/tools/ExternalAccess.java +++ b/libs/entitlement/tools/common/src/main/java/org/elasticsearch/entitlement/tools/ExternalAccess.java @@ -56,6 +56,11 @@ public static EnumSet fromString(String accessAsString) { if ("PUBLIC".equals(accessAsString)) { return EnumSet.of(ExternalAccess.PUBLIC_CLASS, ExternalAccess.PUBLIC_METHOD); } + // used by JDK public API extractor (only), describing protected method access + // in this case public class access can be implied + if ("PROTECTED".equals(accessAsString)) { + return EnumSet.of(ExternalAccess.PUBLIC_CLASS, ExternalAccess.PROTECTED_METHOD); + } if ("PUBLIC-METHOD".equals(accessAsString)) { return EnumSet.of(ExternalAccess.PUBLIC_METHOD); } diff --git a/libs/entitlement/tools/jdk-api-extractor/README.md b/libs/entitlement/tools/jdk-api-extractor/README.md index f1a7225259baf..6098005c8649e 100644 --- a/libs/entitlement/tools/jdk-api-extractor/README.md +++ b/libs/entitlement/tools/jdk-api-extractor/README.md @@ -1,28 +1,39 @@ 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. +- public methods (including constructors) of public, exported classes as well as protected methods of non-final classes. +- any overwrites of public methods of public, exported super classes and interfaces. 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. +The output is compatible with the `public-callers-finder` tool to calculate the +public transitive surface of new additions. See the example below. The following `TAB`-separated columns are written: 1. module name -2. fully qualified class name (ASM style, with `/` separators) -3. method name -4. method descriptor (ASM signature) -5. visibility (`PUBLIC` / `PROTECTED`) -6. `STATIC` modifier or empty -7. `FINAL` modifier or empty +2. unused / empty (for compatibility with `public-callers-finder`) +3. unused / empty (for compatibility with `public-callers-finder`) +4. fully qualified class name (ASM style, with `/` separators) +5. method name +6. method descriptor (ASM signature) +7. visibility (`PUBLIC` / `PROTECTED`) +8. `STATIC` modifier or empty +9. `FINAL` modifier or empty 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 the public apis diff -u libs/entitlement/tools/jdk-api-extractor/api-jdk24.tsv libs/entitlement/tools/jdk-api-extractor/api-jdk25.tsv > libs/entitlement/tools/jdk-api-extractor/api.diff + # extract additions in the new JDK, these require the most careful review cat libs/entitlement/tools/jdk-api-extractor/api.diff | grep '^+[^+]' | sed 's/^+//' > api-jdk25-additions.tsv + +# review new additions next for critical ones that should require entitlements +# once done, remove all lines that are not considered critical and run the public-callers-finder to report +# the transitive public surface for these additions +./gradlew :libs:entitlement:tools:public-callers-finder:run -Druntime.java=25 --args="api-jdk25-additions.tsv true" ``` ### Optional arguments: diff --git a/libs/entitlement/tools/jdk-api-extractor/src/main/java/org/elasticsearch/entitlement/tools/jdkapi/JdkApiExtractor.java b/libs/entitlement/tools/jdk-api-extractor/src/main/java/org/elasticsearch/entitlement/tools/jdkapi/JdkApiExtractor.java index b4f5e4dd1a636..578afb2666b1d 100644 --- a/libs/entitlement/tools/jdk-api-extractor/src/main/java/org/elasticsearch/entitlement/tools/jdkapi/JdkApiExtractor.java +++ b/libs/entitlement/tools/jdk-api-extractor/src/main/java/org/elasticsearch/entitlement/tools/jdkapi/JdkApiExtractor.java @@ -188,6 +188,8 @@ CharSequence toLine(ModuleClass moduleClass) { return String.join( SEPARATOR, moduleClass.module, + "", // compatibility with public-callers-finder + "", // compatibility with public-callers-finder moduleClass.clazz, method, descriptor, diff --git a/libs/entitlement/tools/public-callers-finder/README.md b/libs/entitlement/tools/public-callers-finder/README.md index 794576b3409a8..2a46e2d360998 100644 --- a/libs/entitlement/tools/public-callers-finder/README.md +++ b/libs/entitlement/tools/public-callers-finder/README.md @@ -1,4 +1,5 @@ -This tool scans the JDK on which it is running. It takes a list of methods (compatible with the output of the `securitymanager-scanner` tool), and looks for the "public surface" of these methods (i.e. any class/method accessible from regular Java code that calls into the original list, directly or transitively). +This tool scans the JDK on which it is running. It takes a list of methods (compatible with the output of the `securitymanager-scanner` and `jdk-api-extractor` tools), +and looks for the "public surface" of these methods (i.e. any class/method accessible from regular Java code that calls into the original list, directly or transitively). It acts basically as a recursive "Find Usages" in Intellij, stopping at the first fully accessible point (public method on a public class). The tool scans every method in every class inside the same java module; e.g. @@ -14,11 +15,10 @@ it treats calls to `super` in `S.m` as regular calls (e.g. `example() -> S.m() - In order to run the tool, use: ```shell -./gradlew :libs:entitlement:tools:public-callers-finder:run [] +./gradlew :libs:entitlement:tools:public-callers-finder:run -Druntime.java=25 --args=" []" ``` Where `input-file` is a CSV file (columns separated by `TAB`) that contains the following columns: -Module name -1. unused +1. Module name 2. unused 3. unused 4. Fully qualified class name (ASM style, with `/` separators) @@ -26,7 +26,7 @@ Module name 6. Method descriptor (ASM signature) 7. Visibility (PUBLIC/PUBLIC-METHOD/PRIVATE) -And `bubble-up-from-public` is a boolean (`true|false`) indicating if the code should stop at the first public method (`false`: default, recommended) or continue to find usages recursively even after reaching the "public surface". +And `bubble-up-from-public` is a boolean (`true|false`) indicating if the code should stop at the first public method (`false`: default) or continue to find usages recursively even after reaching the "public surface". The output of the tool is another CSV file, with one line for each entry-point, columns separated by `TAB` diff --git a/libs/entitlement/tools/public-callers-finder/build.gradle b/libs/entitlement/tools/public-callers-finder/build.gradle index 6a350665eee54..0aa05168862fa 100644 --- a/libs/entitlement/tools/public-callers-finder/build.gradle +++ b/libs/entitlement/tools/public-callers-finder/build.gradle @@ -51,7 +51,7 @@ repositories { } dependencies { - compileOnly(project(':libs:core')) + implementation(project(':libs:core')) implementation 'org.ow2.asm:asm:9.8' implementation 'org.ow2.asm:asm-util:9.8' implementation(project(':libs:entitlement:tools:common'))