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

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.

Related

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

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.

In java, do I always need a Main class?

I know that I'll need a main method, but can that main method be in a different class other than the Main class?
Not all Java applications require a main method.
Java can also be used to create web applications, for instance, which don't require main methods to run.
The answer to your question depends on what exactly you mean. Do you mean a class with the name 'Main'? Then, no, there is no requirement for this at all.
The only requirement that Java has, is that the signature of the method is correct. the main method must:
be public
be main
be static
have returntype void
accept an array of Strings as (only) parameter
It's easier to add it in the public class in a file, but not mandatory. The name of the class it is in, is entirely up to you, though many will choose a name like 'Main' or 'Open', simply to more easily find it.
If you want to be able to run your application, by simple double-clicking the .jar file, you'll need to point to the class that contains the main method (to use: your application might contain a lot of main classes, used for internal testing, but only one can be used to start the actual application) in the manifest file: Manifest files
Prior to Java 7, it was possible to run a desktop application without a main method, by (ab)using an instantiation block, but this was removed as of Java 7, because this is not what the instantiation block was intended for.
It's not necessary to define yout main method in a main class. You can place your main method wherever you want, as long the syntax i correct :
public static void main (String[] args){
//...
}
You absolutely don't.
The method itself can be placed whereever you want it to be, there is no limitation.
However, I personally would recommend putting it in a class which at least contains something like "Main", because when others look at your code, and they are not using an IDE which supports jumping to the main method, people usually have an easier time finding your starting point.
However, that is just for sake of readability, and as I said, jumping to main is/should be usually a widespread supported feature
Yes, the Main method is required to run a function although a java class can be without the Main method. Though, it won't run...

why do we use java files without main ? What purposes does it meet ? How useful it is .?

I am new to java programming and i just came across to a java program composed of many files and only one of the file had a main function while others did not. I didn't really understood that why don't we have a main function in every java file.
Not every file needs a "main" function. For example, you may want to import a file with specific function or class. In this case (a java file without a "main" function), the java file simply represents a chunk of code, which is added to your program. So it doesn't need a separate "main" function, if you already have one.
In java, main() is an entry point to a program/application. Sometimes in a application we just need only one entry point to start the program and from this point other necessary code are used.
But not all application necessarily need an main() method - like web application or java applet where a container initiate the application/program.
Every Java program must have an entry point, and that entry point must have a certain signature. Which, as you have noticed, is public static void main(String[] args)
After that, the class that is the entry point can create instances of other classes and/or invoke their methods, or invoke static class-level methods. It is not necessary for those classes to have an entry point, because the program is already running (executing your code) in the Java Virtual Machine (JVM).
You'll notice that a common error novice (and sometimes even seasoned) programmers make is trying to run a program for which the runtime environment cannot find an entry point. E.g., Eclipse: Java, no main method found (in this example, the problem was that the OP had the wrong method signature). The runtime has to find something to, well, RUN.
If your code is going to be run by some other code (e.g., you are developing a library or an API that contains functionality that will be used as part of another application) it may not be necessary for you to have a main method. If you look through the .jar files of some of the standard libraries using your IDE, you should discover that very few of them have classes with a main method - this is because they are not intended to be run alone, but rather in the context of another application.
The public void main(String args[]) method in java is the entry point to the program. If it is run directly, it will start from the main method. However, not every class that you might make in Java is an acceptable entry point. In fact, in many applications, you should have exactly one main method. There is generally not too much need for more. Some java libraries has no main method anywhere at all. This code is generally designed so that it can be used by other java code, and often has no sensible way to run itself. It's not designed to do that. It is designed to help other programs that do.
What classes without a main method are used for, is a) to provide functionality for other java programs (dependancies for instance), b) to provide additional functionality to the program that is invoked through the main method.
Here is a couple example files that illustrate the second.
MainExample.java
public class MainExample{
public static void main(String args[]){
OtherClass other = new OtherClass()
other.doExpensiveComputation1();
other.doExpensiveComputation2();
}
}
OtherClass.java
public class OtherClass{
public void doExpensiveComputation1(){
//do stuff here
}
public void doExpensiveComputation2(){
//do other stuff here
}
}
Now, you might be asking, "couldn't I just write those methods inside the main class?". In some cases the answer might be yes, but for more complex code, it generally isn't. In some cases it will be impractical simply because it clutters up the main class too much to keep track of. It is much easier to keep track of code that keeps its classes in different files.
Execution of Java program always starts from Main method.Class having main method is the entry point for the program and further from there you can get the rest of the desired functionality.
If You want you can have main method in each java file, which will behave as multiple entry points for your program.

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.

Eclipse export as runnable JAR

I know SO dislikes this type of questions but after googling and checking SO for close to an hour I am no closer to a solution. I have a package with some classes which together form a GUI based game which runs fine when I do CTRL-F11 but when I right-click the package->Export->Runnable JAR it is nowhere to be found in the Launch Configuration dropdown, while other packages/projects are.
I would like to be able to run this game outside of Eclipse even if I don't need to now. I have no main methods, my runnable uses acm. public class SokobanGFX extends GraphicsProgram.
Found this in Javadoc:
http://jtf.acm.org/javadoc/student/acm/program/Program.html
"In many programming environments, objects that are specific instances of a Program
subclass will run automatically without any special action on your part. For maximum
portability, you might want to define a static main method as described in the comment
for the standard implementation of main."
Should be easy to make an executable jar after that.
I'm not familiar with ACM, but based on my observations with the Javadoc, I believe:
public static void main(String[] args){
new SokobanGFX().start()
}
//http://jtf.acm.org/javadoc/student/acm/program/Program.html#main(String[])
Should launch the program.

Categories

Resources