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
JaCoCo fails to start when another agent uses UUID prior to JaCoCo #551
Comments
After reading the code, seems like you guys modifiy the UUID class and add the '$jacocoAccess' field to it and try to read it later. I assume that the problem is that JaCoCo is not supporting class-redefinition so if another agent loads the UUID, it doesn't get instrumented, thus, the '$jacocoAccess' field doesn't exist. Thoughts? |
@nadavye JVM loads and starts agents in order in which they are specified in command-line, so make sure that JaCoCo agent is a first one. Or please explain the reasons why you need another agent that uses UUID to be started prior to JaCoCo. |
Even if JaCoCo agent will be marked as |
Hi @Godin, First, I would like to thank you for the quick answer. Second, per your question, I have a Java Agent that runs along JaCoCo and it seems like one of its dependencies creates a UUID. I understand what you are saying about the limitation of OpenJDK. Note that I don't mind donating to the codebase - I just want that the solution will be aligned with your design & internal considerations. |
@nadavye For some background information please see section "Coverage Runtime Dependency" in our architecture documentation. I'm well aware that this is a hack which might cause problems in certain setups. But it is the best solution we found so far. Any new ideas are welcome! Why does the workaround proposed by @Godin not work for you? Can't you put JaCoCo agent as the first agent on the command line? |
@marchof thanks for the link. I'll have a look at it. Per @Godin's solution, note that our javaagent is being used by customers which run JaCoCo next to our agent. When they add our agent, we can't control the order, thus, from time to time we get a ticket about JaCoCo's failure. What do you think about adding an API to JaCoCo that will register that field? This way I'll be include a small dependency in JaCoCo's API and invoke it when my agent initializes. This API will add the transformer that modifies UUID and if it fails, it will fail gracefully. This way, if JaCoCo will be loaded later, the '$jacocoAccess' field will found. I know that's a hack, but it will allow our agents to co-exist. |
In the meanwhile, I'll try to think on more elegant solutions. I'll appreciate if you could also take some time on your end and see what can be done. That being said - I appreciate your fast response time! :-) You guys are awesome 👍 |
BTW - Is there a reason why you choose UUID? Thoughts? |
@nadavye We picked UUID because this class seems not to be used with other agents. Originally it was java.lang.Void but we saw conflicts here with some application servers. I'm strongly against a configuration option. Such technical options cause a lot of support questions. What I could think of is using a list of classes which will tried one after the other. These classes should
|
@nadavye IMO the simplest option is to tell to your users that JaCoCo should be the first one. This is consistent with what we tell to JaCoCo users 😉 And as @marchof I'm also against of configuration option for the same reasons. As well as against proposed API that is IMO more of a hack rather than a solution. The list of classes is an interesting idea, even if there still will be possibility that all of them was loaded. We can improve error message, so to ease understanding that JaCoCo agent should be the first one. |
@marchof As another idea: we use this field to cross boundaries of classloaders, so maybe instead agent can track classloaders for injection of a class into them that will be providing access for classes loaded by this classloader. Classes that are loaded by classloader into which we can't inject classes (one of main java classloader, don't remember name/term of it) believe already have a direct access to agent. |
@Godin Some remarks to your ideas:
|
What about injecting code into each every class which derives of ClassLoader so it will load JaCoCo's classes from a certain location? Is that doable? |
@Godin - I prefer to resolve this issue rather then letting users fail and then tell them that due to limitation in JaCoCo it has to be first. That's bad experience for the customers and it will cause you guys to look bad and we don't want it ;-) |
Mocking frameworks have similar need, so there was a discussion about this and as far as I remember it ended in that JDK 9 will provide dedicated mechanism for such class injection. Will need to refresh my links and memory about that.
And bootstrap classloader is used for base java classes which are of a less interest for majority of our users. For those for whom this is of an interest, there is anyway difficulties such as computation of coverage is impossible for classes used during startup sequence. So maybe classes from bootstrap classloader shouldn't be our concern?
Isn't it just a rephrasing of my idea? And to answer whether this is doable or not, time to think (ref @marchof questions) and to experiment/prototype is required. |
@Godin - may bad. I thought that by "track classloaders" you meant that the agent will keep state. As long as we are on the same page, we are cool. |
@marchof Do you feel that we can modify this method in Premain.java:
To something like:
And then check inside the premain() method if the runtime is null. If that's the case we'll throw an exception that JaCoCo should be the first agent. Thoughts? |
@nadavye Yep, something like this. Maybe you can propose some classes which work with your setup? |
For the record
|
@marchof to my taste potential candidates are:
|
@Godin Nice! For every candidate we should run a little test to see what other classes are loaded when it gets initialized. Just to make sure we don't cause side-effects on our side. |
gives:
Also nothing suspicious and heavy in source code of Given that such replacement is complimentary to improvement of error message - do you have a proposal/idea of a message? |
As a remark: there seems to be a backdoor as another agent can create field |
@nadavye BTW bear in mind that even in case of changes on our side, we can't do anything for older versions, so that with them error still will be there as well as recommendation to change order. I don't know what your agent is doing, but maybe on your side you can delay activity of your agent (especially with class |
@Godin - Thanks for the clarification. I'm aware of it. |
The exception message I would reword as follows:
For the FAQ I would add the following entry:
|
For the record - tiny script to assist with possible candidates:
|
To be 100% sure you'd better check with 0.7.10-SNAPSHOT version of JaCoCo that can be obtained from snapshot repository - http://www.jacoco.org/jacoco/trunk/doc/repo.html
All the changes that were merged into the master and their respective versions as always are reflected on page http://www.jacoco.org/jacoco/trunk/doc/changes.html |
Hi Godin, |
@nadavye please stop repeating question. It will be released when we'll finish work on version. And there is not only your ticket. Thank you for your understanding. |
Sorry, I've thought that you didn't see it as I didn't tag you in the first
post.
My bad :\
Didn't mean to pressure.
…On Tue, Oct 24, 2017 at 11:25 PM, Evgeny Mandrikov ***@***.*** > wrote:
@nadavye <https://github.com/nadavye> please stop repeating question. It
will be released when we'll finish work on version. And there is not only
your ticket. Thank you for your understanding.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#551 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AOZ71MrFvqI7Uq5o_lR-Gw_5eIY2XNFbks5svkeegaJpZM4OAmjJ>
.
--
Kind regards,
Nadav
<https://www.sealights.io/regression-test-code-coverage/>
|
Hi, I saw the same error, wondering whether this get fixed by 0.7.10.201712151226 release or not? Thank you! |
@Charlie7381 please carefully read this thread, specifically - #551 (comment) and #551 (comment) , an you'll be able to answer your question by yourself. |
I consider that #555 in 0.8.0 resolves main story of this ticket. If needed future improvements should be done via separate tickets. |
Version 0.8.0 fixes jacoco/jacoco#551 . And it seems that we have the same problem: 18:58:51 Exception in thread "main" java.lang.reflect.InvocationTargetException 18:58:51 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 18:58:51 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 18:58:51 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 18:58:51 at java.base/java.lang.reflect.Method.invoke(Method.java:566) 18:58:51 at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:513) 18:58:51 at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:525) 18:58:51 Caused by: java.lang.RuntimeException: Class java/util/UUID could not be instrumented. 18:58:51 at org.jacoco.agent.rt.internal_8ff85ea.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:140) 18:58:51 at org.jacoco.agent.rt.internal_8ff85ea.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:101) 18:58:51 at org.jacoco.agent.rt.internal_8ff85ea.PreMain.createRuntime(PreMain.java:55) 18:58:51 at org.jacoco.agent.rt.internal_8ff85ea.PreMain.premain(PreMain.java:47) 18:58:51 ... 6 more 18:58:51 Caused by: java.lang.NoSuchFieldException: $jacocoAccess 18:58:51 FATAL ERROR in native method: processing of -javaagent failed 18:58:51 at java.base/java.lang.Class.getField(Class.java:1999) 18:58:51 at org.jacoco.agent.rt.internal_8ff85ea.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:138) 18:58:51 ... 9 more Version 0.8.2 fixes vaskoz/core-java9-impatient#11 that we have with version 0.8.0. Change-Id: I2fb566289580bf8fecfec0b15fb323bf3548ee8d Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
This is a issue tracker. Please use our mailing list for general questions:
https://groups.google.com/forum/?fromgroups=#!forum/jacoco
Also check FAQ before opening an issue: http://www.jacoco.org/jacoco/trunk/doc/faq.html
Steps to reproduce
Create a javaagent which loads the UUID class and use that agent prior to JaCoCo.
Expected behaviour
JaCoCo should run normally
Actual behaviour
JaCoCo fails with an error similar to the following:
The text was updated successfully, but these errors were encountered: