Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report the current classpath when failing due to not finding a class on the classpath #202

Closed
hakanai opened this issue Sep 13, 2022 · 8 comments · Fixed by #206
Closed
Assignees
Milestone

Comments

@hakanai
Copy link

hakanai commented Sep 13, 2022

We have a series of bizarre build failures where forbidden-apis failed because it couldn't find org.apache.commons.lang3.StringUtils.

Caused by: de.thetaphi.forbiddenapis.ParseException: Class 'org.apache.commons.lang3.StringUtils' not found on classpath file parsing signature: org.apache.commons.lang3.StringUtils#isBlank(java.lang.CharSequence)

Our problem is - we only add the commons-lang3 signatures files to the list, if the task's classpath includes the commons-lang3 jar.
So somehow it seems that:

  • When we call task.classpath and iterate through the classpath, it says commons-lang3 is there. BUT:
  • When the task actually runs, it says commons-lang3 is not there

To figure out which of these is the case, it would be nice if the error message included the classpath it was using for this search. The same build failure doesn't happen when I run the same build locally - it passes!

(As far as investigating the underlying issue, I'm trying an update from v3.1 to v3.3 to see if it magically fixes it.)

@uschindler
Copy link
Member

I will check if I can provide the classpath. The problem is that the Forbiddenapis Checker class only uses a ClassLoader instance. If the ToString of it would be helpful it would be easiest to print it.

@uschindler uschindler self-assigned this Sep 23, 2022
@uschindler uschindler added this to the 3.4 milestone Sep 23, 2022
@uschindler
Copy link
Member

ClassLoader#toString() does not print anything useful. The only chance to get this running is to pass a "human readable string representation" to the ForbiddenApis Checker class next to the classloader. The type of ClassLoader differs between Gradle, Maven and Ant so it is up to their internals how the classloader is built. I don't have access to the original classpath in all cases.

@dweiss
Copy link
Contributor

dweiss commented Sep 24, 2022

Most of those are probably instances of URLClassLoader though, Uwe. It's a cheap shot to try instanceof and then https://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#getURLs() (I've done it in the past).

@dweiss
Copy link
Contributor

dweiss commented Sep 24, 2022

Another cheap-shot alternative is to try to getResource on MANIFEST.MF and enumerate everything possible, listing URLs. I also did this in the past (blush) - this works with non-url classloaders most of the time too.

@uschindler
Copy link
Member

Actually I have access to some path representation in some build system specific way (Path in Ant, Strings of files in Maven and the CLI, a List of File instances in Gradle). I just need to pass an additional string for human consumption to the Checker instance.
But yes, most are URLClassLoader, except Ant.

@uschindler
Copy link
Member

I am not fully happy with it, but I added a PR #206. This also adds DEBUG as log level.

If you have classpath issues you can enable debug logging and it will report more detailed information to JDK type and also the classpath used.

I will maybe rework the PR and remove the classpath logging from the Checker and just always report classpath when task starts (separately for each build system). So see it as preview.

@uschindler
Copy link
Member

uschindler commented Sep 24, 2022

I changed the PR to always report classpath using DEBUG logging on task startup in Maven, Gradle, Ant

@uschindler
Copy link
Member

Now looks like this if you run gradle with --debug:

   [gradle] 13:54:41.664 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':forbiddenApisMain'.
   [gradle] 13:54:41.666 [DEBUG] [org.gradle.api.Task] Classpath: C:\Users\Uwe Schindler\.ivy2\cache\org.apache.ant\ant\jars\ant-1.7.0.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.apache.maven\maven-plugin-api\jars\maven-plugin-api-2.0.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.apache.maven\maven-artifact\jars\maven-artifact-2.0.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.apache.maven.plugin-tools\maven-plugin-annotations\jars\maven-plugin-annotations-3.4.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.gradle\gradle-core\jars\gradle-core-3.4.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.gradle\gradle-base-services\jars\gradle-base-services-3.4.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.gradle\gradle-base-services-groovy\jars\gradle-base-services-groovy-3.4.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.gradle\gradle-logging\jars\gradle-logging-3.4.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.slf4j\slf4j-api\jars\slf4j-api-1.7.7.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.codehaus.groovy\groovy-all\jars\groovy-all-2.4.17.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.ow2.asm\asm\jars\asm-9.3.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.ow2.asm\asm-commons\jars\asm-commons-9.3.jar;C:\Users\Uwe Schindler\.ivy2\cache\org.codehaus.plexus\plexus-utils\jars\plexus-utils-1.1.jar;C:\Users\Uwe Schindler\.ivy2\cache\commons-cli\commons-cli\jars\commons-cli-1.3.1.jar;C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build\classes\main
   [gradle] 13:54:41.674 [DEBUG] [org.gradle.api.Task] Detected classical classpath-based JDK @ [C:\Program Files\Java\jdk1.8.0_272\jre\, C:\Program Files\Java\jdk1.8.0_272\jre\lib\]
   [gradle] 13:54:41.683 [INFO] [org.gradle.api.Task] Reading bundled API signatures: jdk-unsafe-1.7
   [gradle] 13:54:41.703 [INFO] [org.gradle.api.Task] Reading bundled API signatures: jdk-deprecated-1.7
   [gradle] 13:54:41.751 [INFO] [org.gradle.api.Task] Reading bundled API signatures: jdk-non-portable
   [gradle] 13:54:41.752 [INFO] [org.gradle.api.Task] Reading bundled API signatures: jdk-reflection
   [gradle] 13:54:41.752 [INFO] [org.gradle.api.Task] Reading bundled API signatures: jdk-system-out
   [gradle] 13:54:41.754 [INFO] [org.gradle.api.Task] Reading API signatures: C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\src\tools\signatures\mysignatures.txt
   [gradle] 13:54:41.760 [INFO] [org.gradle.api.Task] Loading classes to check...
   [gradle] 13:54:41.773 [INFO] [org.gradle.api.Task] Scanning classes for violations...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment