-
Notifications
You must be signed in to change notification settings - Fork 36
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
Gradle plugin's forbiddenApisMain throws ClassNotFoundException despite compileJava succeeding #109
Comments
Hi. theoretically, the compile classpath should be fine for forbidden-apis checks. It can just happen under some circumstances that - luckily - javac does not need to look into superclasses of types found in code. But those types should be available on compile classpath, too (e.g., a newer version of javac may possibly also look into them). In contrast, forbiddenapis has to look into types more thorougly, because if you forbid a very generic superclass, code that uses any subclass of it should also be forbidden. Typical example: On the other hand, the runtime classpath is also not 100% correct. A workaround if you trigger such issues is to redefine the "classpath" property of forbiddenapis to point to the runtime. By default it is initialized with the compile classpath, but that's easy to override!: forbiddenApisMain {
classpath = project.sourceSets.main.runtimeClasspath;
} FYI: This issue is similar to #43 |
In the above stack trace it looks like the following is happening:
|
I guess PicoContainer's Startable is a very common interface for random things to implement and it's very likely that some component somewhere has implemented it, but we never call start on whatever it is, so we never hit the issue. So I guess I really have two options:
I bet each has its pros and cons, and I bet that leaving it off would result in devs complaining about compile failing when they just ran the compile from IDEA and it worked. (The task of getting forbidden-apis to run alongside the IDEA compiler is difficult.) :D |
Another alternative to investigate is to add the picocontainer element to forbiddenapis classpath only: forbiddenApisMain {
classpath += libraries.picocontainer // not sure how to do this correctly, just as idea
} |
True enough. I could also potentially do something like this:
But I do fear what a future javac might do, so maybe I'm better off just adding the dependency and changing the way I check whether the build is still OK. |
+1 looks like a cool workaround. Anyways, another quick solution is: |
Can I close this issue? |
I ended up changing my tool to run forbiddenApisMain to check for missing classes, because I can't know whether a future javac might load more classes than the current one. |
Got bitten by one of these again, and starting to think that it would be really helpful if it printed out the chain of references resulting in trying to load the class. At the moment, I have a vague "couldn't find this class", but there are no direct references to it from the project being checked, so I have to somehow figure out where the indirect references might be, which I don't have any tools to help with. Created #142 to track this. |
I have been trying to crack down on incorrect dependencies in our projects and have a tool in the making which automates removing random dependencies or replacing "compile" with "testCompile" to see if the build still works. If it still works, it removes the line.
Overnight (the tool takes forever because our build is slow) it removed a line which somehow broke running forbiddenApisMain but I'm not quite sure why.
The one particular module can still compile:
But when I run the checks:
Indeed, the line it had just removed from the build was:
So seemingly I have ended up with a module where the classpath used for compiling is adequate for compiling but not adequate for forbidden-apis to perform its checks. I'm still trying to figure out how this can be possible.
We do turn off transitive dependencies for all our compile dependencies, as part of trying to ensure that random rubbish isn't pulled into our compile classpath, to stop people accidentally importing the wrong classes and to encourage proper encapsulation of dependencies. So my initial hunch is that perhaps forbidden-apis is running with the compile classpath but should be running with the runtime classpath, or a modified version of the compile classpath with transitive dependencies turned on.
The complete stack trace is as follows:
The text was updated successfully, but these errors were encountered: