kordamp / jdeps-gradle-plugin Goto Github PK
View Code? Open in Web Editor NEWRun JDeps on a Gradle build
License: Apache License 2.0
Run JDeps on a Gradle build
License: Apache License 2.0
I tried running this on one of my smaller projects and wound up with 210 lines of console output. I imagine that my larger projects will be even larger.
I would like to have this plugin output to build/reports
, the standard location for Gradle reports (used by the PMD plugin, Java unit tests, etc). I would be fine with it either outputting all the time or optionally outputting as a configuration option.
Tried new branch commit but permission denied. If it helps here is the code I wrote to get the -include option working. Needed this option to restrict jdeps package scans to our own code, because JDK 11 jdeps was failing on our pre-Java 9 code due to multiple dependency files (not controlled by us) using the jdk.unsupported classes.
`class JDepsReportTask extends DefaultTask {
@input boolean verbose = false
@input boolean summary = false
@input boolean profile = false
@input boolean recursive = false
@input boolean jdkinternals = true
@input boolean consoleOutput = true
@input @optional List configurations = ['runtime']
@input @optional List classpaths = ['compileClasspath', 'runtimeClasspath', 'testCompileClasspath', 'testRuntimeClasspath']
@input @optional List sourceSets = ['main']
@input @optional Integer multiRelease
@input @optional Map<String, Integer> multiReleaseJars = [:]
@input @optional String include = null
private Object reportDir
JDepsReportTask() {
extensions.create('moduleOptions', ModuleOptions)
}
@TaskAction
void evaluate() {
ModuleOptions moduleOptions = extensions.getByType(ModuleOptions)
JavaCompile compileJava = project.tasks.findByName(JavaPlugin.COMPILE_JAVA_TASK_NAME)
String classpath = compileJava.classpath.asPath
List<String> compilerArgs = compileJava.options.compilerArgs
/** #prevent global leak with per module record output for multimodule.
For much larger project, Could be further improved with a buffer so it won't eat the heap further...
**/
List<String> commandOutput = []
final List<String> baseCmd = ['jdeps']
if (summary) baseCmd << '-s'
if (verbose) baseCmd << '-v'
if (profile) baseCmd << '-profile'
if (recursive) baseCmd << '-recursive'
if (jdkinternals) baseCmd << '-jdkinternals'
if (include) {
baseCmd << '-include'
Regex regex = new Regex(include)
baseCmd << regex.pattern
}
if (JavaVersion.current().java9Compatible) {
if (multiRelease) {
baseCmd << '--multi-release'
baseCmd << multiRelease.toString()
}
if (classpath) {
baseCmd << '--module-path'
baseCmd << classpath
} else {
int modulePathIndex = compilerArgs.indexOf('--module-path')
if (modulePathIndex > -1) {
baseCmd << '--module-path'
baseCmd << compilerArgs[modulePathIndex + 1]
}
}
if (!moduleOptions.addModules.empty) {
baseCmd << '--add-modules'
baseCmd << moduleOptions.addModules.join(',')
} else {
int addModulesIndex = compilerArgs.indexOf('--add-modules')
if (addModulesIndex > -1) {
baseCmd << '--add-modules'
baseCmd << compilerArgs[addModulesIndex + 1]
}
}
}
compileJava.classpath = project.files()
project.logger.info("jdeps version is ${executeCommand(['jdeps', '-version'])}")
sourceSets.each { sc ->
SourceSet sourceSet = project.sourceSets[sc]
project.logger.info("Running jdeps on sourceSet ${sourceSet.name}")
sourceSet.output.files.each { File file ->
if (!file.exists()) {
return // skip
}
project.logger.info("jdeps command set to ${baseCmd.join(' ')}")
String output = JDepsReportTask.executeCommandOn(baseCmd, file.absolutePath)
if (output) {
commandOutput << "\nProject: ${project.name}\n${output}".toString()
}
}
}
for (String c : configurations) {
inspectConfiguration(project.configurations[c], baseCmd, commandOutput)
}
for (String c : classpaths) {
inspectConfiguration(project.configurations[c], baseCmd, commandOutput)
}
if (commandOutput) {
commandOutput = commandOutput.unique()
if (consoleOutput) println commandOutput.join('\n')
File parentFile = getReportsDir()
if (!parentFile.exists()) parentFile.mkdirs()
File logFile = new File(parentFile, 'jdeps-report.txt')
logFile.append(commandOutput)
}
}
`
The current Gradle wrapper for the project is 3.5, which is incompatible with JDK 10. Building the project means that the user has to switch to an older version of Java.
I tried to upgrade the wrapper myself, but trying 4.0 or later gave me the following error:
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/Will/OpenSource/jdeps-gradle-plugin/build.gradle' line: 61
* What went wrong:
A problem occurred evaluating root project 'jdeps-gradle-plugin'.
> java.lang.NullPointerException (no error message)
Line 61 contains this code: compile files(org.gradle.internal.jvm.Jvm.current().toolsJar)
. It looks like the internal implementation has changed.
I'm not entirely sure what it's doing, but regardless, it doesn't work on Gradle 4.x.
After updating to 0.8.0
I started getting a million of those:
Exception in thread "main" java.lang.module.FindException: Unable to derive module descriptor for /home/boris/.gradle/caches/modules-2/files-2.1/org.apache.tika/tika-parsers/1.22/b8a823128f6165882ae41de3ded8655609d62d88/tika-parsers-1.22.jar
at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:646)
at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:329)
at java.base/jdk.internal.module.ModulePath.scan(ModulePath.java:235)
at java.base/jdk.internal.module.ModulePath.scanNextEntry(ModulePath.java:188)
at java.base/jdk.internal.module.ModulePath.findAll(ModulePath.java:164)
at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:558)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class org.apache.tika.parser.external.CompositeExternalParser not in module
at java.base/jdk.internal.module.ModulePath.deriveModuleDescriptor(ModulePath.java:553)
at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:642)
... 9 more
This is using Gradle 6.0 RC1 and Java 13. Any ideas?
I think the task can be made to depend on the inputs of the sourcesets that are configured and not run if there are no changes.
On this line:
...
Caused by: java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:231)
at org.kordamp.gradle.plugin.jdeps.tasks.JDepsReportTask.evaluate(JDepsReportTask.groovy:269)
...
This is on Gradle 7.0.2. Version 0.12.0 works fine.
Using org.kordamp.gradle.jdeps
version 0.17.0 and running the jdepsReport
task, I get the following error:
Exception in thread "main" java.lang.module.FindException: Error reading module: C:\workspace\testproject\build\classes\java\main
at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:350)
at java.base/jdk.internal.module.ModulePath.scan(ModulePath.java:237)
at java.base/jdk.internal.module.ModulePath.scanNextEntry(ModulePath.java:190)
at java.base/jdk.internal.module.ModulePath.findAll(ModulePath.java:166)
at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:521)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
Caused by: java.lang.module.InvalidModuleDescriptorException: Unsupported major.minor version 61.0
at java.base/jdk.internal.module.ModuleInfo.invalidModuleDescriptor(ModuleInfo.java:1088)
at java.base/jdk.internal.module.ModuleInfo.doRead(ModuleInfo.java:192)
at java.base/jdk.internal.module.ModuleInfo.read(ModuleInfo.java:129)
at java.base/jdk.internal.module.ModulePath.readExplodedModule(ModulePath.java:689)
at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:320)
... 8 more
Using Gradle 7.3.3
Java 17 with preview features enabled
The problem seems to not happen in version 0.16.0.
Running jdeps
under Gradle 6 results in the following warnings:
> Task :backend:jdeps
Property 'failOnError' has redundant getters: 'getFailOnError()' and 'isFailOnError()'. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'jdkinternals' has redundant getters: 'getJdkinternals()' and 'isJdkinternals()'. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'profile' has redundant getters: 'getProfile()' and 'isProfile()'. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'recursive' has redundant getters: 'getRecursive()' and 'isRecursive()'. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'summary' has redundant getters: 'getSummary()' and 'isSummary()'. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'failures' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Hi, I tried to generate the dot graph, but got
rbrunet@forward-desktop:~/git/analytics$ gradle --info jdeps --verbose --dot-output=summary
Initialized native services in: /home/rbrunet/.gradle/native
Initialized jansi services in: /home/rbrunet/.gradle/native
The client will now receive all logging from the daemon (pid: 219809). The daemon log file: /home/rbrunet/.gradle/daemon/7.2/daemon-219809.out.log
Starting 28th build in daemon [uptime: 25 mins 57.605 secs, performance: 100%, non-heap usage: 31% of 256 MiB]
Using 8 worker leases.
Now considering [/home/rbrunet/git/analytics] as hierarchies to watch
Watching the file system is configured to be enabled if available
File system watching is active
Starting Build
Settings evaluated using settings file '/home/rbrunet/git/analytics/settings.gradle'.
Projects loaded. Root project using build file '/home/rbrunet/git/analytics/build.gradle'.
Included projects: [root project 'analytics']
> Configure project :
Evaluating root project 'analytics' using build file '/home/rbrunet/git/analytics/build.gradle'.
Applying dependency management to configuration 'bootArchives' in project 'analytics'
Applying dependency management to configuration 'archives' in project 'analytics'
Applying dependency management to configuration 'default' in project 'analytics'
Applying dependency management to configuration 'implementation' in project 'analytics'
Applying dependency management to configuration 'compileOnly' in project 'analytics'
Applying dependency management to configuration 'compileClasspath' in project 'analytics'
Applying dependency management to configuration 'annotationProcessor' in project 'analytics'
Applying dependency management to configuration 'runtimeOnly' in project 'analytics'
Applying dependency management to configuration 'runtimeClasspath' in project 'analytics'
Applying dependency management to configuration 'testImplementation' in project 'analytics'
Applying dependency management to configuration 'testCompileOnly' in project 'analytics'
Applying dependency management to configuration 'testCompileClasspath' in project 'analytics'
Applying dependency management to configuration 'testAnnotationProcessor' in project 'analytics'
Applying dependency management to configuration 'testRuntimeOnly' in project 'analytics'
Applying dependency management to configuration 'testRuntimeClasspath' in project 'analytics'
Applying dependency management to configuration 'apiElements' in project 'analytics'
Applying dependency management to configuration 'runtimeElements' in project 'analytics'
Applying dependency management to configuration 'developmentOnly' in project 'analytics'
Applying dependency management to configuration 'productionRuntimeClasspath' in project 'analytics'
All projects evaluated.
Selected primary task 'jdepsReport' from project :
Tasks to be executed: [task ':compileJava', task ':processResources', task ':classes', task ':jdepsReport']
Tasks that were excluded: []
:compileJava (Thread[Execution worker for ':',5,main]) started.
> Task :compileJava
Watching 15 directories to track changes
Watching 15 directories to track changes
Watching 15 directories to track changes
Watching 15 directories to track changes
Resolving global dependency management for project 'analytics'
Excluding []
Excluding []
Caching disabled for task ':compileJava' because:
Build cache is disabled
Task ':compileJava' is not up-to-date because:
Output property 'destinationDirectory' file /home/rbrunet/git/analytics/build/classes/java/main has been removed.
Output property 'destinationDirectory' file /home/rbrunet/git/analytics/build/classes/java/main/com has been removed.
Output property 'destinationDirectory' file /home/rbrunet/git/analytics/build/classes/java/main/com/forward has been removed.
Watching 15 directories to track changes
Watching 15 directories to track changes
Watching 15 directories to track changes
Watching 14 directories to track changes
The input changes require a full rebuild for incremental task ':compileJava'.
Full recompilation is required because no incremental change information is available. This is usually caused by clean builds or changing compiler arguments.
Compiling with toolchain '/home/rbrunet/toolbox/jdk-17'.
Compiling with JDK Java compiler API.
Class dependency analysis for incremental compilation took 0.0 secs.
Created classpath snapshot for incremental compilation in 0.018 secs.
Watching 22 directories to track changes
Watching 24 directories to track changes
Watching 26 directories to track changes
Watching 27 directories to track changes
:compileJava (Thread[Execution worker for ':',5,main]) completed. Took 0.51 secs.
:processResources (Thread[Execution worker for ':',5,main]) started.
> Task :processResources NO-SOURCE
file or directory '/home/rbrunet/git/analytics/src/main/resources', not found
Skipping task ':processResources' as it has no source files and no previous output files.
:processResources (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
:classes (Thread[Execution worker for ':',5,main]) started.
> Task :classes
Skipping task ':classes' as it has no actions.
:classes (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
:jdepsReport (Thread[Execution worker for ':',5,main]) started.
> Task :jdepsReport FAILED
Watching 28 directories to track changes
:jdepsReport (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jdepsReport'.
> Input property 'resolvedDotOutput' with value '/home/rbrunet/git/analytics/summary' cannot be serialized.
* Try:
Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 845ms
2 actionable tasks: 2 executed
Watching 28 directories to track changes
As seen at https://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4 jdeps --list-deps
might need access to the module-path
Otherwise the value base
cannot be set.
Looking at how the Maven jdeps plugin behaves, I'd like the Gradle plugin to fail my build when there are jdeps errors.
An example is that JUnit includes a multi-version jar, and I need to tell jdeps
what Java version to check for.
The plugin detects "Warning:" but not "Error:"
Using ignoreMissingDeps
in the configuration don't add parameter --ignore-missing-deps
in the jdeps command line.
To test it, use a jar with log4j-api-2.17.2.jar
dependency.
Error: Missing dependencies: classes not found from the module path and classpath.
To suppress this error, use --ignore-missing-deps to continue.
log4j-api-2.17.2.jar
org.apache.logging.log4j.util.Activator -> org.osgi.framework.AdaptPermission not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.AdminPermission not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.Bundle not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.BundleActivator not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.BundleContext not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.BundleEvent not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.BundleListener not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.InvalidSyntaxException not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.ServiceReference not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.SynchronousBundleListener not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.wiring.BundleWire not found
org.apache.logging.log4j.util.Activator -> org.osgi.framework.wiring.BundleWiring not found
The releases page for this project does not show the new 0.2.0 release.
I'm seeing this when moving to Gradle 7.1 from 7.0.2:
* What went wrong:
Execution failed for task ':jdepsReport'.
> Configuration with name 'runtime' not found.
My only configuration in build.gradle
is:
jdepsReport {
multiReleaseJars = [".*": "$jdkVersion"]
}
I don't have multi-release jars, but some dependencies do.
Works fine with Kotlin <= 1.4.31:
$> git clone https://github.com/McPringle/moodini.git
$> cd moodini
$> ./gradlew check
Build successful! Now change Kotlin version in gradle.properties
from 1.4.31
to 1.5.0
(line 19) and run check
again:
$> ./gradlew check
Build fails:
> Task :jdepsReport FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jdepsReport'.
> Configuration with name 'runtime' not found.
I know, the configuration names changed in Gradle. But I did not change my Gradle version, just the Kotlin compiler version. I did both runs with Gradle v7.0.1 and jdeps 0.12.0. There is no project-specific jdeps configuration in my build file.
Invocation of Task.project at execution time has been deprecated. This will fail with an error in Gradle 8.0. Consult the upgrading guide for further information: https://docs.gradle.org/7.6/userguide/upgrading_version_7.html#task_project
This is shown when running the jdepsReport
task on a Gradle 7.6 project.
As titled, I'm trying to run it on a multi-release jar (lwjgl), but I get:
Error: lwjgl-jemalloc-3.2.3-SNAPSHOT-natives-windows.jar is a multi-release jar file but --multi-release option is not set
It seems the command line can become too long (in my case):
Execution failed for task ':jdepsReport'.
> org.zeroturnaround.exec.ProcessInitException: Could not execute [jdeps, --multi-release, base, --class-path, C:\Users\USER\.gradle\caches\modules-2\files-2.1\org.projectlombok\lombok\1.18.22\9c08ea24c6eb714e2d6170e8122c069a0ba9aacf\lombok-1.18.22.jar;<MANY MORE JARS>]. Error=206, Filename or extension too long
This parameter is helpful as input to building a reduced JRE with jlink
.
To future-proof and to support various implementations, I'd like to be able to pass arbitrary options to jdeps , e.g., --api-only or --dot-output, via the plugin.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.