Is there a way to detect the end of the bootstrapping phase of the JVM?
edit::
so to provide a bit more context, what i am trying to do is to instrument the JDK. And this is a full blown instrumentation that records every LOAD, STORE, INVOKE byte code instruction. As the instructions are executed their data is sent to a static method, that is loaded from the xbootclasspath. This static method captures all this information and stores all of this as a trace for performing analysis at a later time.
Now, when i do this for the JDK, i do not want to disturb the way classes are loaded in the JVM, which might result in a program crash. I was guessing that the best way to go about it is to detect the point in time when the JVM is done bootstrapping, so that I can safely turn on my instrumentation thereafter. (I plan to not instrument any of the code, while the bootstrapping is taking place.) Is this even the right way to go about it?
In addition to my previous comment about looking into FERRARI and MAJOR I want to say several things:
Both tools are only available for download as compiled Java JAR archives.
So I wrote to the scientists who have created those tools today and asked them our question. As soon as I will receive an answer I will report back here.
Anyway, I have looked into FERRARI's architecture and think I may have found out how they do it.
So here is my educated guess (still untested) about what you could do:
Instrument your JDK classes.
Add one simple class BootstrapLock as described below.
Re-pack the instrumented + the new class into a modified rt.jar.
Write a little dummy Java agent as described below.
public class BootstrapLock {
private static volatile boolean inBootstrap = true;
public static boolean inBootstrap() {
return inBootstrap;
}
public static synchronized void setEndOfBS() {
inBootstrap = false;
}
}
public class DummyAgent {
public static void premain(String options, Instrumentation ins) {
BootstrapLock.setEndOfBS();
}
}
So basically the logic is as follows:
Agents are loaded before the main application class, but after bootstrapping.
Thus the very fact that the agent is active means that bootstrapping is finished.
Thus the agent can switch off the global marker inBootstrap.
Your instrumented classes can check the marker in order to determine if their additional instrumentation code should be bypassed or not.
I am unsure if I have enough time to test this anytime soon, but at least I wanted to post this answer here so maybe you, Vijai, can also look into it and provide some feedback. Four eyes see more than two...
Update: One of the FERRARI authors has answered my inquiry and confirmed my explanation above. You can just use a java agent as a marker of JVM having finished its bootstrapping. Maybe you do not even need the additional class, but just check if the agent has been loaded into the JVM yet. It would make things even simpler, I just do not know if it performs well. Just test it.
Related
I am building a Java library of a few Java, Maven projects. There is no main method in any of the projects since it is a library. In web applications, you can create a class that implements ServletContextListener and it will execute when your server starts (e.g. when Tomcat starts). I want to do the same, but for the library (which is not a web application or a console application. It is just a reusable library). If someone writes a program that uses my library, I want my initialzer class to execute when the JVM starts in order to do some initialization I want it to do. How could I do that?
Thank you
If you add a JAR as a -javaagent: on the command line, a premain method will be called before the main of the program you are running.
e.g.
import java.lang.instrument.Instrumentation;
public class Agent {
public static void premain(String args, Instrumentation instrumentation){
// early initalization
}
}
https://zeroturnaround.com/rebellabs/how-to-inspect-classes-in-your-jvm/
You want specific initialization code always to be executed at first, before a (Java) library is being used.
The J2EE/Spring option using #PostConstruct has already been addressed for the question posed. Using Java SE, you can encapsulate your Java library by a singleton class - a class which is the 'entrance' to the rest of the functionality of your library.
The constructor of the singleton class can call all necessary initialization code, before passing control back to the caller (the main web-application).
public class LibraryInstance {
private FunctionalClass1 functionalClass1;
private FunctionalClass2 functionalClass2;
...
private LibraryInstance() { runInitializingCode(); }
private static final LibraryInstance instance = new LibraryInstance();
public static LibraryInstance getInstance() {
return instance;
}
private void runInitializingCode() {
....
}
}
Should work out-of-the-box.
I guess the question boils down to how you can initialise your objects before they’re used. This, in turn, depends on what data you need to perform your initialisation. If you need:
to perform initialisation work that is not dependent on outside information, then you can do this at object creation (eg in a constructor or, if you’re using an EE framework, in something like a #PostConstruct annotated method), or in a static initialisation block that will be run at class loading time.
data from your user’s environment, static calls in the System class can provide this. Again, this can be done at object construction time.
static choices users have made about how to use your library, consider using a property file (which will need to be documented). Again, object construction is the time to do this.
dynamic choices users have made about using your library, this will be available at runtime somewhere within the objects collaborating with your library.
If your initialisation work is resource intensive and you want to do it when your user’s app starts, then I think the best way to achieve this is to document the requirement and ask users to call specific methods that will perform the initialisation.
From a library user perspective, I want to know when your library does initialisation work and how heavy that work is. I don’t want a library making decisions about when it will consume resources, particularly at startup when I might have lots of my own startup code, framework code and countless other bits of initialisation all contributing to startup lag.
Edit: Just to be clear, all of these options are at the application level. The JVM itself is already up and running. We’re talking about initialisation of application code and not the JVM.
Question Setup
There are a few moving parts to this question, so I will try to do my best to replicate the issue in its simplest form.
I am attempting to add a TrayIcon to a SystemTray. This is typically a very simple objective on operating systems ("platforms") that support the call (this will play an integral part in a few moments).
I am programming for and on a Windows machine, presently (this is not a question about interoperability).
Here's the logic behind the code I've got that works:
public class SomeClass {
public static void main(String[] args) {
if(SystemTray.isSupported()) {
// DO SOMETHING TO ADD AN ICON
}
}
}
With all of its inclusions, this works. However, what I am really after, is the ability to inject the SystemTray instance with it's icon already "ready to go".
That code looks something a little more like this:
public class SomeClass extends NecessarySpringExtension {
private #Setter(onMethod=#_#Resource(name="SystemTrayControl"))) SystemTrayControl systemTrayControl;
// The above uses Lombok, as well.
public static void main(String[] args) {
// DO SOME RELATED STUFF like setting the configurations for
// for the application
}
}
The resource returns an instance (#Bean) of the SystemTrayControl class which, itself, makes a call to SystemTray; however, now, SystemTray is no longer supported (see some explanation in the The Question section, below).
Some Change Detail
Here's a snippet of some of that code (obviously, I've got my head submerged in the issue. Let me know if the context needs expanding. My belief is the following should be enough code to give you a sense of the structure):
SystemTrayControl Class:
#PostConstruct
public void showIcon() {
if (SystemTray.isSupported()) {
val tray = SystemTray.getSystemTray(); ....
Resource Class:
#Configuration
public class BeansForNeeds {
#Bean
public SystemTrayControl systemTrayControl() {
return new SystemTrayControl():
} ....
For the sake of more context: if I remove the condition seen in the SystemTrayControl class , I get a HeadlessException (which I've done a bit of reading on).
The Question
The issue stems from that fact that when utilizing a SpringApplicationBuilder in your program, the .headless property defaults to true. The javadoc states:
Sets if the application is headless and should not instantiate AWT.
Defaults to true to prevent java icons appearing
If I manually set the property to false, then the application runs well; however, I am always a bit "shaky" overwriting default behavior, particular if the language of "prevents" x, y, or z makes into the mix.
So, the question is:
Why is the property defaulted to true? What are the side effects of allowing the behavior prohibited by .headless? What's it got against AWT?
Once upon a time, pulling in the AWT classes (and native stuff) on a true headless box like Unix without X would cause runtime exceptions and other nasty OS level failures. And the errors would only happen once the classes were loaded, so it could be slightly non-deterministic.
This was with Java 6 or so, I recall.Things may have changed since then. And I suppose it is important that it was a problem only for the AIX Java, which is a clean-room Java that is not based on the Sun reference implementation. It wasn't strictly a bug, though, because the reference implementations just escaped the same problem by mistake when I looked at the code for each.
In my case, we had to be careful in some startup code to not accidentally use a handy utility class if it touched AWT, because then all of it would be pulled in, and fall over as it ran into missing native UI. This would never happen on Windows, where a lot of development took place. But once deployed on a true headless AIX box the app would fail hard with a runtime exception that bubbled right up to the user.
This is because we had "client" code (that was, ostensibly, headless and did not rely on the any UI code) and "UI" code (that knew how to interact with a command line or a full Swing GUI.) The client code was changed such that it pulled in some handy utility class (I forget which one) but this caused the VM to pull in some other classes, which pulled in AWT, which hit some native code expecting there to be a native UI of some sort.
Since the AIX box had no X, these native components were not there, and the whole thing fell apart with a translated native/runtime exception.
So, not only did we have to run the VM headless, we had to make sure our code did not accidentally reference any AWT code, either directly or indirectly.
I'd want to do more research to see how this scenario interacts with the property discussed here, but the key takeaway for me is that cross-platform means cross-platform! And "headless" can mean something very specific on different platforms.
EDIT: There must be some way I can approach this without writing a whole new debugger. I'm currently looking into ways to build on top of the existing java debugger. If anyone has any ideas on how to grab information the Java debugger already has (about stack frames, variables, raw data etc.), that would be really helpful.
--
What I'm trying to do is I have this framework/API built on Java, and I would like to write an eclipse plugin debugger that is customized to my framework. Here is a simple example:
I have two classes, one called scope and one called variable. The scope holds a map of variables. The code is all in java, but I'm using this scope-variable relationship almost like a new language, and would like a variable debug tab that gives me a list of currently active scopes with the variables that are currently stored inside. Here is some code:
import java.util.Hashtable;
public class Scope {
private Hashtable<String, Variable> variableList = new Hashtable<String, Variable>();
// constructor
public Scope(){
}
public void put(String key, Variable v){
variableList.put(key, v);
}
public Variable get(String key){
return variableList.get(key);
}
}
public class Variable {
private String value;
private String name;
public Variable(String aName, String aValue){
name = aName;
value = aValue;
}
public String getValue(){
return value;
}
public String getName(){
return name;
}
public void setValue(String aValue){
value = aValue;
}
}
This is obviously an extremely simple example, but I would like to accomplish something similar to this where I can get a variables window, set a breakpoint, and have a "debugger" list out my active scope objects and the variable objects inside.
I've been trying to read and understand: http://www.eclipse.org/articles/Article-Debugger/how-to.html
and its pretty dense (as well as extremely outdated), but I will try to take some time to understand it. I just wanted to see if anyone had any high level recommendations on how to approach this type of problem, as I have little experience developing plugins in eclipse or making debuggers.
Thanks!
Not an easy task. That article is still the main reference, I think. Old, but not outdated. Try to digest it, and preferably to make it work. Before it, you should have a minimal experience developing Eclipse plugins.
There are many pieces in the picture, but the first thing you must understand is that when Eclipse is debugging something (assuming we are using the standard debug model), we have two separate "worlds": the Eclipse side, and the interpreter side (or, if you prefer, the "local" and "remote" sides).
Int the Eclipse side, the programming involves a cooperation between some Eclipse core classes and some classes of your own, which extend or implement some Eclipse classes/interfaces:
A "launchConfigurationType" (extension point in your plugin.xml) which causes the apparition of a new custom configuration when you click "Debug As -> New Configuration); this goes togetther with some "launchConfigurationTabGroups" definition that defines the "Tabs" dialogs that will appear in your custom launch configuration (eg) (each Tab will have its own class typically).
The launchConfigurationType is typically associated to a LaunchDelegate class, which is sort of your bootstrap class: it has the responsability of creating and starting a running/debugging instance, both on the Eclipse side and on the "interpreter" (or "remote") side.
On the Eclipse side, the running/debugging instance is represented by a IDebugTarget object and its children (the implementation is your responsability); this is created by the LaunchDelegate and "attached" to the remotely running process at launching time.
The remote side, the interpreter or program you are actually debugging, can be anything: a binary executable, a perl script, some app running in a some site (perhaps also a local Java program; but, even in this case, this would probably run in its own JVM, not in the debugging Eclipse JVM!). Your IDebugTarget object must know how to communicate to the "remote interpreter" (eg, by TCP) and perform the typical debugger tasks (place breakpoints, step, run, ask for variables, etc) - but the protocol here is up to you, it's entirely arbitrary.
What is not arbitrary is the hierarchy of your custom classes that the running Eclipse debugger will use: these should have a IDebugTarget as root, and should implement "The debug model" (see figure in article). As said above, the IDebugTarget object is who understands how to make the translation between the EClipse side and the remote side (see this image)
having worked on the eclipse edc debugger, it sounds like writing a whole debugger is not so much what you want.
it sounds like while running the debugger, you will have access to the objects that have the variables and scopes you are interested in.
you can use toString() in the classes themselves or use detail formatters to display a variation on the information you want. the toString() call can get quite detailed and nest into calls, show whole arrays, etc. detail formatters can also be quite complex.
see http://www.robertwloch.net/2012/01/eclipse-tips-tricks-detail-formatter/ . it's the best of several URLs (i have no association with the author).
once you are happy with the output of the Variable and Scope objects, you should be able to add watch expressions that will always show them in your expressions window (thus you don't have to rely on local variables in the stack frame you may be in).
this should then give you the list of Variables and Scopes from your framework that you are tracking … hopefully without having to write an entire eclipse debugger plugin to do so.
ok, i'm going to add a second answer here … i guess i'm not familiar enough with the state of your environment to know why custom detail formatters would not do the trick. for most cases, i think they'll provide you what you're looking for.
but if you're really interested in creating another view holding these items, then you could check out the eclipse jdt project . it's entirely possible that the extension points it provides will give you access to the internal variables and stack-frame information that you're looking to add, and also perhaps some UI that will make your job easier.
in other words, you might not have to write an entirely new debugger plugin, but perhaps a plug-in that can work together with jdt.
the site has pointers to the project plan, source repositories, the bugzilla issue tracking database (used for both bug-tracking and new feature discussion). perhaps some of those who are experts on jdt can help weigh in with their opinions about what will best suit your needs.
So, given the following code:
public MyInterface getMyInterface() {
return new MyInterface() {
public SomethingElse getSomethingElse() {
// ....
}
}
}
...
MyInterface obj = getMyInterface();
Is there some way to instrument a call to getSomethingElse() on that obj? To go in and do some bytecode modification or something?
I have production code in there that in a different situation (call it "design time") I want to add some tracing/logging and such code for help in troubleshooting and analysis. Performance is critical for the production case so I want to leave it without the extra tracing/logging overhead. But in the design time situation, I want to have all the trace info.
Yes, it is possible to do what you're asking, although there are definitely better ways to accomplish it - the most obvious would be to create a default implementation of MyInterface, and then a "tracing" subclass of it that extends and logs before invoking the superclass version.
If instrumentation is your only option, then when running at design time, you can start your project with a java agent in Java 5 or add a java agent to the classpath at runtime in Java 6. See the instrumentation documentation.
To instrument the class, you will probably want to use a tool like ASM. The steps would be something like this:
In your Agent class, implement java.lang.instrument.ClassFileTransformer .
In your agentmain() or premain() method, request to transform classes.
When you receive a call to the transform method, you can check if the class implements MyInterface by using Class.getInterfaces().
Optionally, you can check to see if its Class.getEnclosingClass() is the class in which you wrote/found this code.
If the Class passes these sanity checks, then create a ClassWriter that adds logging to the getSomethingElse() method. The ASMifier helps a lot when trying to figure out how to generate the code you want.
Then, in production, none of that code will exist. In development, you would add your Java Agent in your environment, which would enable your debugging.
Again, there are almost certainly better ways to do this, but there are good reasons to use instrumentation, and this is a mini-crash course in doing it.
Hope that helps,
If you want to turn on logging on in development, the simplest thing to do is
if(LOGGER.isDebugEnabled())
LOGGER.debug("my debug message");
The over head added is sub-nanosecond so even if you are working on a system where every nano-seconds count, this is still the best pattern to use.
You can get the class with
Class.forName("package.OuterClass$NNN");
You need to call a constructor which takes an instance of the outer class.
This sounds like a good case for using aspects.
You can simply apply logging/tracing code around any methods you want in your testing environment and leave them out when you move to production.
I am looking for a way to remove all uses of a particular class, including the class itself, at compile time. Basically a form of pre-processing, but I'd like to do it without having to surround all the instances with #ifdebug ... #endif.
Is there any ant-based tool out there that can do this? If not, can anyone point me in the right direction for how to write such a tool? (not a minor undertaking I know, but if its the only option...)
The situation is I have a helper class for debugging function calls. This is instantiated at the beginning of a function and a call is made at the end. This is a JavaME application so I'm nervous about the overhead this is adding to performance. I already have a release and debug build that have pre-processor directives using ProGuard, so I would like to exclude the use of this helper class from the release build. It doesn't appear this can be done with ProGuard.
"This is instantiated at the beginning of a function and a call is made at the end. "
If this is all over your code maybe you need to look at AOP.
or a state design pattern for the helper class, in test mode it does one thing but in prod it does another(like nothing)
Do you know that this debug code will make the JavaME app slow? You could also try creating a way to conditionally call these debug methods.
A few more ideas ... I've never written a JavaME app, but I assume there is way to run/test with running on the actual device. Given this way of running/testing, perhaps you can use Eclipse/Netbeans to debug your code and use proper breakpoints instead of programmatically tracing method calls. No harm to compiled code in this case. Also consider using AspectJ to trace method calls, this can be conditionally done after code is compiled since AspectJ alters bytecode directly (not sure how this plays with JavaME). Lastly, I've heard of people using the standard GNU C/C++ preprocessor on Java. I have no idea if it works, google will help you.
Not exactly what you want but...
You could separate your code to modules (core and debug, in your case), then make sure modules call each other via reflection: use an interface available in core, create a wrapper class in core that will hide object instantiation via reflection detail/
Then, on production, just omit the debug code and have the wrapper "do nothing" if the instantiation fail / when you set a specific flag.
This way your debug classes won't make it into production and you won't have to "statically link" to them so your core production code won't care.
Of course, this is only possible if your debug code has no side effects visible to core code, but it seems that's your case (from your problem description).
Is it possible to just create the class once, on application startup, instead of creating an instance for each method? Your debug class could then look like this:
public class Debug // maybe make this a *gasp* singleton?
{
public static void start(); // called at start of method
public static void end(); // called at end, probably should be in a finally block
public static void setDebugMode(boolean debugOn); // turn off for production mode
}
Set debug mode to "true" in testing but "false" in production. When debug mode is off, none of the methods do anything (except check the state of debug mode, of course).
You don't avoid the overhead of the function call, and you do need to check the state of that boolean, but you do get to avoid jumping through hoops trying to avoid load the class at all.
This will need more work if you have a multithreaded application, too.