On Wed, 19 Jun 2024 17:53:12 GMT, Maurizio Cimadamore <mcimadam...@openjdk.org> wrote:
>> This PR adds a new JDK tool, called `jnativescan`, that can be used to find >> code that accesses native functionality. Currently this includes `native` >> method declarations, and methods marked with `@Restricted`. >> >> The tool accepts a list of class path and module path entries through >> `--class-path` and `--module-path`, and a set of root modules through >> `--add-modules`, as well as an optional target release with `--release`. >> >> The default mode is for the tool to report all uses of `@Restricted` >> methods, and `native` method declaration in a tree-like structure: >> >> >> app.jar (ALL-UNNAMED): >> main.Main: >> main.Main::main(String[])void references restricted methods: >> java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment >> main.Main::m()void is a native method declaration >> >> >> The `--print-native-access` option can be used print out all the module >> names of modules doing native access in a comma separated list. For class >> path code, this will print out `ALL-UNNAMED`. >> >> Testing: >> - `langtools_jnativescan` tests. >> - Running the tool over jextract's libclang bindings, which use the FFM API, >> and thus has a lot of references to `@Restricted` methods. >> - tier 1-3 > > src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassResolver.java line > 126: > >> 124: >> 125: private static Map<String, String> packageToSystemModule() { >> 126: List<ModuleDescriptor> descriptors = ModuleFinder.ofSystem() > > Is it a problem that we compute the package -> module map using the runtime > info (so latest version) but then all the other info is taken from a > release-specific symbol file? E.g. say that package "foo" was moved from > module "A" to module "B" in version N, and that user passes N - 1 as release > to the scan tool - would that work? That's a good point, I don't think that scenario will work. We should really use the release specific info if we can. I think that's relatively easy to do, will take a look. > src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java > line 81: > >> 79: >> 80: Map<ScannedModule, Map<ClassDesc, List<RestrictedUse>>> >> allRestrictedMethods; >> 81: try(ClassResolver classesToScan = >> ClassResolver.forScannedModules(modulesToScan, version); > > Could it make sense here to "chain" the two resolvers into one, and just pass > the chained one to the restricted finder? We need to scan all the classes in the `classesToScan` resolver, but only look for restricted methods in the system resolver. So, they need to stay separate. > src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java > line 165: > >> 163: restrictedUses.forEach(use -> { >> 164: switch (use) { >> 165: case >> RestrictedUse.NativeMethodDecl(MethodRef nmd) -> > > should user be able to filter output using an option? E.g. say if they are > only interested in restricted methods but not JNI (seems remote, but adding > it here for completeness) That's a good suggestion, but to pull on that string some more, there's also the possibility of filtering based on class/package/method names. Maybe for a followup? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/19774#discussion_r1646564392 PR Review Comment: https://git.openjdk.org/jdk/pull/19774#discussion_r1646563349 PR Review Comment: https://git.openjdk.org/jdk/pull/19774#discussion_r1646566299