-
Notifications
You must be signed in to change notification settings - Fork 10.9k
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
Enhancement - Internal Logging Facade #6566
Comments
Thanks for the report and for digging up the links. The downsides in #829 would still be concerns, but maybe there are other things we could do to help.
|
The platform logger would be ideal, where you could use |
Huh, thanks, I'd totally forgotten about that. @dogourd, any idea whether that would solve your particular problem with Guava+JBoss? (Even if not, it's something for us to consider for general configurability, especially building on what I hope will be the success of conditionally using our first Java 9+ API in Guava, as we were discussing last week.) |
Actually, it doesn't work. The reason for the failure to start JBoss is that we manipulated I think adding a switch is a viable solution, but personally, I'm not fond of using System property to control it. Its scope is too broad as both the javaagent and the application may rely on Guava but be loaded by isolated class loaders. Moreover, we only want to control the logging behavior of Guava components within the javaagent, whereas the System property approach would affect all Guava instances under different class loaders. |
static final Supplier<Logger> logger = Suppliers.memoize(() -> Logger.getLogger(Xyz.class.getName()));
logger.get().log(Level.WARNING, msg); |
@ben-manes Yeah, based on the scenarios I've encountered so far (where |
Ah, interesting. The logger in I should be able to change the I might worry a little about doing that for all our loggers, if only because of the extra classes it would require, which would be unfortunate for our Android users. But we could make the change only in guava-jre (at the cost of a small diff vs. guava-android), or we could reduce the cost by declaring a single class in each package that contains all the loggers for the package. But it should be fine to try out with one class, especially one that already contains a large number of supporting classes. If you comment out the loggers (and their usages) in those two classes, does everything work? I could try to deal with all the loggers now, but I'm trying to take care of a few different Guava things at once, so it's nice if I know where I can take the quick and dirty approach :) |
For this use-case, how worthwhile is it for guava to support it? I would think that an agent should have minimal dependencies to avoid surprises. If you only need the cache then you could try caffeine, which uses the platform logger. Another option is to shade and strip out the logging by bytecode rewriting. |
Thanks, those are both things I intended to say but forgot :( Definitely use Caffeine if you can. And, as I'll be pointing out in the release notes, we don't test Guava usage from a Java agent (as you can tell from the crashes... :)), so I don't know how likely it is to continue working. It's easy enough for us to work around the specific problem we've been discussing here, but you might encounter problems in the future, and if things get hard to fix, we might give up. |
To put it further, can I think of this class as a
Yes, based on my current situation, removing these two loggers can solve the problem.
Yes, actually I lean more towards this being a JBoss issue. Any component within the Javaagent that is capable of bridging to While debugging the initialization process of
I completely understand your point, and I agree. Guava indeed provides many excellent and practical features, such as BTW, in the discussion so far, there have been multiple mentions of using Regarding whether it's worth it for Guava to address this problem, I have my doubts as well. I have another solution in mind where I can make my Javaagent run in a separate thread with a delayed start, ensuring that it initializes after JBoss startup. It would appear like an Attach operation. This is currently the least invasive solution, although it may sacrifice some functionality of the Javaagent due to the limitations imposed by the JVM on retransformClass. |
@dogourd have you considered shading the dependency and using a rule to remove the logger during the byte code transform? |
@ben-manes I'm afraid I don't want to go that route. I'd rather ditch some of the Guava APIs before the bytecode transformation is completed. |
This is progress toward addressing the Java agent / `premain` problem discussed in #6566. (And we're careful to avoid lambdas and method references so as to avoid #6565.) RELNOTES=Fixed some problems with [using Guava from a Java Agent](#6566). (But we don't test that configuration, and we don't know how well we'll be able to keep it working.) PiperOrigin-RevId: 542247494
(I have changes to address both loggers out for review.)
While I wouldn't present it as a configurable factory, I would say that we might be able to put in some kind of conditional along the lines of " |
This is progress toward addressing the Java agent / `premain` problem discussed in #6566. (And we're careful to avoid lambdas and method references so as to avoid #6565.) RELNOTES=Fixed some problems with [using Guava from a Java Agent](#6566). (But we don't test that configuration, and we don't know how well we'll be able to keep it working.) PiperOrigin-RevId: 542887194
If you don't wanna use WeakMap<ClassLoader, Map<String, String>> clProperties;
String getProperty(String key) {
Map<String, String> properties = clProperties.get(Thread.currentThread().getContextClassLoader());
if (properties != null) {
return properties.get(key);
}
return System.getProperty(key);
}
void setProperty(String key, String value) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Map<String, String> properties = clProperties.get();
if (properties == null) {
properties = new HashMap<>();
clProperties.put(cl, properties);
}
properties.put(key, value);
} I've come across similar code in some libraries before, but, um, it's hard for me to say whether it's good or bad, you know. |
(i.e., roll back cl/265490471) This is progress toward addressing the Java agent / `premain` problem discussed in #6566. GWT-RPC support has been gone for a while now. RELNOTES=Fixed some problems with [using Guava from a Java Agent](#6566). (But we don't test that configuration, and we don't know how well we'll be able to keep it working.) PiperOrigin-RevId: 542234757
(i.e., roll back cl/265490471) This is progress toward addressing the Java agent / `premain` problem discussed in #6566. GWT-RPC support has been gone for a while now. RELNOTES=Fixed some problems with [using Guava from a Java Agent](#6566). (But we don't test that configuration, and we don't know how well we'll be able to keep it working.) PiperOrigin-RevId: 543484764
Related discussions that already exist: #829
Added internal logging facade to provide user optionality for using logging implementation.
In some special scenarios (javaagent + jboss), when using guava in javaagent, some APIs of guava will cause
j.u.l.LogManager
to be initialized prematurely, and eventually cause jboss to fail to start.Consider adding a log facade to support users to choose what they want The desired log implementation.
related discussion: Failed initializing module org.jboss.as.logging
The text was updated successfully, but these errors were encountered: