How to run an initializer method in Java when JVM starts? - java

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.

Related

Why JavaFX Application.launch() takes class as an argument?

I'm new to javaFx and looked a bit into source code and have a question regarding
Application.launch function that is used to start an app.
Signature looks like this:
public static void launch(Class<? extends Application> appClass, String... args)
And my question is why it doesn't look like this:
public static void launch(Application app, String... args)
What authors try to achieve by taking class as an argument?
Because an instantiation of the Application is a complex task which FX developers have to have the control over.
The Application instantiation:
requires "FX toolkit" to be initialized in advance
differs for the desktop, jnlp and plugin modes
requires the specific timing
should be called on the special "launcher" thread
should trigger the application lifecycle events
should read the application parameters (from CLI or jnlp file)
Thus you provide only class name to launch and JavaFX do all the work required, including creating an object for you.
I think one of the reason is that this way it more works like it would when you could launch directly through "java my.pkg.MyApp" which you can now in Java8/FX8 because it is on the classpath.
For a definitive answer you'd probably have to ask at the openjfx-mailing list.
The class argument denotes the immediately enclosing class of the method that called launch
Probably, they are using Reflection under the hood. Something like, get the name of the class as an argument to launch() then call the start() of that class.
As with other questions on Stack where people ask what the authors were trying to achieve, we are not privy to the decisions they make.

Running Java code in Eclipse without main

I have a Java project(running in Eclipse) without main method and need to debug and see which is the caller class and the flow of the program. How do I start?
It is a simple project and does not contain any web/tomcat related data.
Thank you for your responses. I am new to StackOverflow and so pardon my writing and asking questions.
I am including packages and trying to create objects of a class, but it is not recognizing the classes. All the classes are public.
There is no way to run a Java SE application without starting with public static void main. If you want to debug the code of a library or framework you need to create a main method and call the code from there.
Take a look to JUnit. If you just want to debug your code is what you normally have to do.
Since Java requires all methods and variables to be within classes, the JVM needs a starting point that exists before any objects are initialized. Therefore, main must be static and public for the JVM to find it. Unlike C++, the main method does not return a status code, so it is of return type void rather than int.

detect the end of the bootstrapping phase of the JVM

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.

How can I run my code upon class load?

Is there a feasible way to get my own code run whenever any class is loaded in Java, without forcing the user explicitly and manually loading all classes with a custom classloader?
Without going too much into the details, whenever a class implementing a certain interface read its annotation that links it with another class, and give the pair to a third class.
Edit: Heck, I'll go to details: I'm doing an event handling library. What I'm doing is having the client code do their own Listener / Event pairs, which need to be registered with my library as a pair. (hm, that wasn't that long after all).
Further Edit: Currently the client code needs to register the pair of classes/interfaces manually, which works pretty well. My intent is to automate this away, and I thought that linking the two classes with annotations would help. Next, I want to get rid of the client code needing to keeping the list of registrations up to date always.
PS: The static block won't do, since my interface is bundled into a library, and the client code will create further interfaces. Thus, abstract classes won't do either, since it must be an interface.
If you want to base the behavior on an interface, you could use a static initializer in that interface.
public interface Foo{
static{
// do initializing here
}
}
I'm not saying it's good practice, but it will definitely initialize the first time one of the implementing classes is loaded.
Update: static blocks in interfaces are illegal. Use abstract classes instead!
Reference:
Initializers (Sun Java Tutorial)
But if I understand you right, you want the initialization to happen once per implementing class. That will be tricky. You definitely can't do that with an interface based solution. You could do it with an abstract base class that has a dynamic initializer (or constructor), that checks whether the requested mapping already exists and adds it if it doesn't, but doing such things in constructors is quite a hack.
I'd say you cleanest options are either to generate Code at build time (through annotation processing with apt or through bytecode analysis with a tool like asm) or to use an agent at class load time to dynamically create the mapping.
Ah, more input. Very good. So clients use your library and provide mappings based on annotations. Then I'd say your library should provide an initializer method, where client code can register classes. Something like this:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Or, even better, a package scanning mechanism (example code to implement this can be found at this question):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
Anyway, there is basically no way to avoid having your clients do that kind of work, because you can't control their build process nor their classloader for them (but you could of course provide guides for classloader or build configuration).
If you want some piece of code to be run on any class loading, you should:
overwrite the ClassLoader, adding your own custom code at the loadClass methods (don't forget forwarding to the parent ClassLoader after or before your custom code).
Define this custom ClassLoader as the default for your system (here you got how to do it: How to set my custom class loader to be the default?).
Run and check it.
Depending on what kind of environment you are, there are chances that not all the classes be loaded trouugh your custom ClassLoader (some utility packages use their own CL, some Java EE containers handle some spacific areas with specific classLoaders, etc.), but it's a kind of aproximation to what you are asking.

Java - how much logic to put in the main class?

How much logic do you normally put in the main class? Should logic in the main class be at minimum, only instantiating other, specialized classes, and running all the tasks from there?
If you have any suggestions on this topic (or external articles), I'd appreciate it.
For small tools, I'm happy to have most or all of the logic in the main class - there tends to be less of a model to work with. (For very small tools, I confess I usually don't bother with unit tests. In particular, there's less benefit on the design side of things than there is if you're building something which will be a component in a larger app.)
For large scale apps, the main class is really just involved with setting things up and getting them in motion. If you're using a DI framework that can be very little code indeed; if you're not using dependency injection then the main class often acts as a "manual" dependency injection framework.
Should logic in the main class be at minimum, only instantiating other, specialized classes, and running all the tasks from there?
Yes. main method and its surrounding class should ideally be used only as an entry point to start the program. The mere existence of the surrounding class is just an artifact of the way Java programs are composed (everything must be inside some class), and there's no reason why it should contain other stuff in addition to the main method (but there definitely are reasons why it shouldn't).
When you get the interesting classes (those that form the actual program) separated, you open doors for all kinds of flexibility. Perhaps some of those classes could be used in some other projects. Perhaps some day you'll want to replace some of them with better implementations. Maybe you'll find a better order to instantiate all those classes - so just swap a few lines. Or how about executing lengthy startup loadings and instantiations in parallel threads? Just wrap some of them to suitable Executors. Good luck trying this with a 1000+ line main class.
This kind of flexibility matters for everything except maybe for 100-line elementary examples, prototypes and such. But given that even small tools tend to grow, why not do it correctly right from the beginning?
It's not so much a question of whether a class is "the main class". It's a question of how much logic is in the public static void main(String args[]) method. Ideally, it should contain very little logic. It should essentially construct one or two objects, and then call methods on those objects. One of those objects might be a this() - an instance of the main class, and that's ok.
You have to put the main() method somewhere - there's no need to create a special class just to hold that method.
As a general rule, try to avoid having too much in static methods - static methods can't be mocked for testing.
The main class should be an entry point to your program and should thus be relatively small. However this all depends on your actual program. If it's 50 lines long, it might be overkill to create two files for it.
As an example, consider the default Swing Application Framework Desktop Application as it would be generated by the NetBeans template, which is simple and short, and whose main() method is a single line that launches it:
public class MyApp extends SingleFrameApplication {
#Override protected void startup() {
show(new MyView(this));
}
#Override protected void configureWindow(java.awt.Window root) {}
public static MyApp getApplication() {
return Application.getInstance(MyApp.class);
}
public static void main(String[] args) {
launch(MyApp.class, args);
}
}

Categories

Resources