How many JVM calling main inside main - java

class B {
public static void main(String[] args) {
}
}
class A {
public static void main(String[] args) {
B.main(args);
}
}
In the above flow, my init method is A.main which in turn calls B.main.
I know calling A.main will spawn a JVM. Does calling B.main inside A.main spawn another JVM?
OR
B.main is JUST another static method once a JVM is started on A.main as init function.

Option 2. The mains are just static methods of each class, and only one JVM is running when making the call from A to B.main(args).
You can also make use of this in JUNIT tests to help check the command line launch behaves as expected, such as
#Test void coverage() {
A.main(new String[] { "a","b" }); // or B.main
// assertions here if there is some output state you could check
}

Related

How to send variable between classes while multithreading

This a much simplified version of my multithreading project and its just a way to replicate the issue in a simpler way for easy understanding.
So I have two classes startSession.java and main.java
what I am trying to do is to send a variable from startSession.java to main.java and Im also using multithreading. However, the problem I am facing is that everytime I try to retrieve the variable inside main I get a null value.
Inside startSession theres the run method and Setter(setSessionKey(String sess)) and getter(getSessionKey()) methods. I hardcoded a variable to test.
The get method only works inside the run method but when I call getSessionKey() from inside main I get a null as seen below. However, this is only a problem when I am using multithreading. When I dont use multithreading and instead just call the run method from inside main, the variable Im looking for is no longer null.
My question is there a way to send a variable from startSession to main while using multithreading ?
thank you
startSession.java
public class startSession extends Thread {
static String sessionKey;
public void run() {
String createdSession = "83248329";
setSessionKey(createdSession);
System.out.println("Inside run method: " + getSessionKey());
}
public String getSessionKey() {
return sessionKey;
}
public void setSessionKey(String sess) {
sessionKey = sess;
}
}
main.java
package com.Server;
public class Main {
static String session;
public static void main(String[] args) throws InterruptedException {
startSession startSession = new startSession();
startSession.start();
session = startSession.getSessionKey();
System.out.println("Inside Main: " + session);
}
}
with multithreading
without multithreading
Use a BlockingQueue whereby the Thread (Producer) will add to the shared queue and the Main (Consumer) will block on the take
main
public static void main(String[] args) throws Exception {
// example only uses 1024 - check what is best for you
BlockingQueue queue = new ArrayBlockingQueue(1024);
StartSession producer = new StartSession(queue);
....
System.out.println(queue.take());
startSession
String createdSession= "83248329";
queue.add(createdSession);
see https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html
and
https://jenkov.com/tutorials/java-util-concurrent/blockingqueue.html

Why It is not going to work with method which is after main method?

I am automating web application. I want to run methods parallel , So have written code like :
public class test{
public static WebDriver driver;
public static void main(String args[])
{
driver = new FirefoxDriver();
}
public static void Login()
{
driver.get("www.example.com");
driver.findElement(By.id("uname")).sendKeys("test");
driver.findElement(By.id("pass")).sendKeys("test");
}
}
When I run the program , it just opens browser and then nothing. Why is it not going inside Login method?
Where are you calling the Login method from the main?
public static void main(String args[])
{
driver = new FirefoxDriver();
Login();
}
What do you mean by I want to run the methods in parallel?
Someone will have to call the Login() method to do the work ... Currently, its just defined but not in use ...
You need the call the Login() method inside main() to execute it.
public static void main(String args[]) {
driver = new FirefoxDriver();
Login();
}
I want to run methods parallel.
You need to create threads and launch them for running any code in parallel in java.
Main is the starting point for any java program. Once it starts executing the Main method, you can launch multiple thread by implementing Runnable interface or extending Thread class. You would need to define the parallel thread code by overriding run() method.

How do you get event notifications back to the main program class of a Java console app?

I'm coming to Java from C#, and I'm really just trying to figure out how to do things in Java world. I'm running Java 8 in IntelliJ IDEA. I found this explaining events in Java as basically being hand-made through manual registration and an interface method call. The code example has enough problems that I assume it was never compiled. After cleaning that up a bit I have this:
Interface MetronomeEvent:
public interface MetronomeEvent {
void Tick(Date tickDate);
}
Class EventFiringSource:
public class EventFiringSource {
// Our collection of classes that are subscribed as listeners of our
protected List<MetronomeEvent> _listeners=new ArrayList();
// Method for listener classes to register themselves
public void addMetronomeEventListener(MetronomeEvent listener)
{
_listeners.add(listener);
}
// "fires" the event
protected void fireMetronomeEvent()
{
if (_listeners != null && !_listeners.isEmpty())
{
for (MetronomeEvent e:_listeners)
{
e.Tick(new Date());
}
}
}
public void Start()
{
fireMetronomeEvent();
}
}
Main console application:
public class MainApp implements MetronomeEvent {
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
source.addMetronomeEventListener(this); // Adds itself as a listener for the event
source.Start();
}
public void Tick(Date tickDate)
{
System.out.println(tickDate.toString());
}
}
The one remaining error is source.addMetronomeEventListener(this); where the compiler complains that it cannot reference MyApp.this from a static context. That makes sense, but I don't see any way then that I could, after implementing the MetronomeEvent interface on the main program class, actually pass it to source.addMetronomeEventListener() for registration. Is it impossible to directly register the main program class for events? Am I supposed to create and register a Listener class that implements MetronomeEvent and will act on behalf of the main application? Like this?
public class Listener implements MetronomeEvent {
public void Tick(Date tickDate){
System.out.println(tickDate.toString());
}
}
And then:
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
Listener l=new Listener();
source.addMetronomeEventListener(l); // Adds another object to listen on behalf of main()
source.Start();
}
This is not about events, it's about main() and static methods in general.
I would suggest writing your main() as
public static void main(String[] args) {
new MainApp(args).execute();
}
This way you're immediately jumping from static function world into object-oriented world.
Based on Vince Emigh's comment/answer I was led to this Oracle doc on lamda expressions and to this one on method references. I've found 3 ways to do this so far.
1) Anonymous class:
source.addMetronomeEventListener(
new MetronomeEvent() {
#Override
public void Tick(Date tickDate) {
System.out.println("anonymous class:");
System.out.println(tickDate.toString());
}
}
); // Adds itself as a listener for the event
2) Lambda expression:
source.addMetronomeEventListener(d -> System.out.println("lambda:\n"+d.toString()));
3) Method reference, which is the closest to what I am accustomed to. A method is defined in the main class:
public static void processTick(Date tickDate){
System.out.println("method reference:");
System.out.println(tickDate.toString());
}
...and then in the body of main() it is added as an event handler like this:
source.addMetronomeEventListener(MainApp::processTick);

Is there a way to execute a block of code in java without putting it in static main method

If I want to just test a block of Java code, is there a way to run it without putting it in a function?
Public static void main(String[] args){
//block of code
}
Also, how do I execute a static block of code like below?
static {
//block of code
}
You can create static blocks
public class StackOverflowUser {
public static StackOverflowUser god;
static {
god = new StackOverflowUser("Jon Skeet");
}
//Stoof
}
Which will do something (hopefully) at some point during the program's life span. The truth is, there's no telling when it fires, and it's not well documented and may change from JVM to JVM. It will definitely have fired before you make the first call to that class, but it could have been executed any time between right before your call and JVM init.
You can also create just constructor blocks
public class StackOverflowUser {
private static ArrayList<StackOverflowUser> users = new ArrayList<StackOverflowUser>();
{
users.add(this);
}
//Stoof
}
This will activate before the constructor is called, right before. Basically, right after object creation, but before initialization. Don't try messing with too many fields, because they won't have been set.
In terms of order, all blocks work the same way. Once the first block has been called, the second block, third block, etc. will all follow, as Jayan puts it "in textual order".
Static blocks get executed once the class is loaded or initialized. So if you want to test the code inside the static block, the best way is to create an instance of the class.
if you want to test your code the best way is to use some testing framework like JUnit or testng.
static block will be executed when your class is being loaded first. So it can be used for DB instantiation etc. where you are sure that this block will be executed before your other code run.
simple block {...} will run when you try to create an instance.
Here first this block will be called then the code written below your line containing new keyword will be called.
public class Test3 {
public static void main(String[] args) {
Test3 obj = new Test3();
}
{
System.out.println("hussain akhtar wahid");
}
}
public class StaticBlockTest {
/*
* Some Code Goes Here
*
* */
static {
System.out.println(" Static Block Executed ");
System.exit(0);
}
}
Static block gets executed without the need for the main method and you need to pass the System.exit(0) to terminate the currently running Java Virtual Machine to exit the program execution.

Declaring the main method synchronized

I saw a Java example that had a main method labeled as synchronized, calling another static synchronized method. The effect is that, basically, the other method runs on the separate thread only after the main method has returned.
What practical functionality would such a construct have?
public class SynchronisedMain {
public static synchronized void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
#Override
public void run() {
thingy();
}
}).start();
System.out.println("Kickstarted thingy thread.");
TimeUnit.MILLISECONDS.sleep(1000);
}
public static synchronized void thingy() {
System.out.println("Thingy!");
}
}
It's probably useful as a makeshift "application closed handler", doing some cleanup duty before the app finishes entirely. It's pretty contrived though...
There is nothing that says the main function can only be used as the entry point to a program. Being static, there is no reason other classes couldn't call SynchronisizedMain.main(). Being synchronized prevents multiple instances from being executed concurrently which might be desirable.

Categories