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
Agent opens access to java.base to unnamed module #1328
Comments
Hi @DanielThomas unfortunatelly it is not possible to implement a Java agent with on-the-fly instrumentation without any side effects. We need a way of communication between the instrumented classes and the JaCoCo runtime to collect coverage data. Please see "Coverage Runtime Dependency" in the implementation design chapter. Any ideas how to implement the agent without adding dependencies are welcome! You can use offline instrumentation. In this case you have to set-up the runtime dependency manually. |
@marchof I couldn't find it documented, but I believe you can use Add-Opens in the manifest and you wouldn't need that code at all. It appears that's how NewRelic got their agent working for JDK 16: newrelic/newrelic-java-agent#366 |
@DanielThomas As said before, contributions for this are welcome! If you build JaCoCo there is a quite extensive (integration) test suite, so you will immediately see whether other approaches work. |
…acoco#1328 This avoids opening java.base/java.lang to the entire unnamed module.
It appears if this was necessary, it no longer is. All tests pass without this logic.
It appears if this was necessary, it no longer is. All tests pass without this logic.
Quoting https://openjdk.org/jeps/261
So definitely not something that will help to solve the issue described here 😉 Moreover quoting the same https://openjdk.org/jeps/261
Unfortunately while implementing #829 we forgot that the agent is loaded by the application class loader and thus in the same unnamed module causing issue described here. If the agent will have a different module, the problem described here will go away. We asked whether agent can be a real module (not unnamed) in https://groups.google.com/g/jacoco-dev/c/NNP863PDuto/m/OVrNp2WUAAAJ
Unfortunately corresponding ticket https://bugs.openjdk.org/browse/JDK-6932391 is still open nowadays 😞 Fortunately https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.3.6 states
🎉 To demonstrate this:
produces
even when executed with JaCoCo agent. So this can be used for our |
Not impossible - you can run tests without JaCoCo agent for such verification 😉 However I fully agree that will be better to have the ability to do such verification without disabling JaCoCo. And find it interesting that this was unnoticed for more than three years - does it mean presence of @DanielThomas Thank you for reporting this! 👍 🤗 ❤️ |
@Godin amazing, that's a great find! Temporarily turning off the agent is indeed not a big deal because once we've dealt with illegal accesses in our migration, I doubt they'll regress again. I only found this because I fixed this in Gradle and wondered why I still couldn't get my test to fail: Yeah, I'd guess folks are adding opens everywhere. We're trying to avoid that and so far, it's all backwards compatible library upgrades or small fixes to internal code. Really appreciated. Do you or the project have sponsorships somewhere or have a cause you'd like me to donate to on your behalf to say thanks? |
Test failures are caused by jacoco/jacoco#1328, explicitly pin that version so we can perform the upgrade. JIRA: INFRAUTILS-100 Change-Id: I44cfe9b98cefb3422dbee2a28c83c6859798a8fe Signed-off-by: Robert Varga <robert.varga@pantheon.tech> (cherry picked from commit c76c506)
Test failures are caused by jacoco/jacoco#1328, explicitly pin that version so we can perform the upgrade. JIRA: INFRAUTILS-100 Change-Id: I44cfe9b98cefb3422dbee2a28c83c6859798a8fe Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
This is only for JDK >= 16. Without this fix some unit tests that uses Mockito will fail with the following error: ``` Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @cafebabe ``` We notice this error only after upgrade JaCoCo to version 0.8.9 because prior this version the error was being hide by a side effect of JaCoCo. See: jacoco/jacoco#1334 See: jacoco/jacoco#1328 See: #86 (comment) See: #86 (comment) See: #86 (comment) See: #87 This is a workaround and the added profile should be removed in the future in order of a definitive fix (maybe Mockito upgrade). This reverts commit 31a8d68.
We're migrating to JDK 17 and found that we were unable to run tests with JaCoCo to verify code was not accessing encapsulated Java internals in the
java.base
package.Steps to reproduce
Given class
IllegalAccess.java
and JDK 17:Run without Jacoco and note the exception:
Run with Jacoco and no exception is thrown:
Expected behaviour
The agent should not cause runtime side effects to code under test. This in particular makes it impossible to verify production code doesn't perform illegal accesses at test time causing this code to fail when deployed.
Actual behaviour
The agent adds
java.base
to the exported modules for the unnamed module causing the entire classpath to be granted access.The text was updated successfully, but these errors were encountered: