How to stop a maven project started in Netbeans - java

I have a project in NetBeans that starts with a main function, that takes arguments. When I hit the "Stop" Button, the project continues running, but there is no output anymore.
Currently I have to remember to manually stop the process from the console.
How can I modify my project, maven setup or NetBeans configuration to make the process halt when I hit stop.
I can live with the process not having its finalizers or ShutdownHooks called.
Consider this class:
public class Main {
public static void main(String[] args) {
System.out.println("args: " + Arrays.asList(args));
new Main().action();
}
private void action() {
Date start = new Date();
long endTime = start.getTime() + 600000;
Date end;
do {
synchronized (Thread.currentThread()) {
try {
Thread.currentThread().wait(1000);
System.out.println("PING");
} catch (InterruptedException iex) {
return;
}
}
end = new Date();
} while (end.getTime() < endTime);
}
}
I want it to die using only NetBeans Stop button.

When you hit "Stop" in the NetBeans output, NB stops the maven process, but maven had spawned the actual program output, so the stop command is not handed over to your program.
NetBeans calls the exec-maven-plugin with the 'exec' goal by default. If you change it to the 'java' goal there is no new process. After the change below, the 'Run' section in your projects 'Properties' will be empty and of no use. I did not test what happens if you call 'System.exit' or similar in this scenario.
Also note, that you have to take care that you modify the version number here by yourself from now on.
You have to go to Projects window, right click your project, go to the Properties and select the Actions element and the the Run project entry. It will look like this:
You have to modify
Execute Goals: to process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:java (change the exec in the end to java).
Set Properties: to
exec.mainClass=de.steamnet.stopfromnetbeans.Main
exec.classpath=%classpath
exec.args=First Second 'Third Space'
So that it looks like this:
From now on, Maven will not fork a new process, so when you hit "Stop" it will actually Stop the process.

Related

Not able us Virtual Threads using Project Loom

I was exploring the Virtual Threads in Project Loom. The Documents say it as straight forward with simple lines of code as below:
Thread.startVirtualThread(() -> {
System.out.println("Hello, Loom!");
});
Or
Thread t = Thread.builder().virtual().task(() -> { ... }).start();
I have tried both of them, For the first one, I receive an error
The method startVirtualThread(() -> {}) is undefined for the type Thread
And for the second one
- The method builder() is undefined for the type Thread
One browsing, found that lombok is required, Installed lombok as well. However it doesn't show up in Eclipse About section, I am able to use lombok, But still my issue is not resolved.
Below link show the documentation, I am referring to.
enter link description here
Sample Code:
public class threads {
public void simpleThread() {
Thread start = Thread.builder().virtual().task(() -> {
System.out.println("Hello World");
}).start();
Thread.startVirtualThread(() -> {
System.out.println("Hello, Loom!");
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub
threads trd = new threads();
trd.simpleThread();
}
}
It looks like older versions of Eclipse is giving a compilation error when calling the new Thread methods related to Loom.
Please try to use the latest Eclipse (currently 2020-09) with an OpenJDK Project Loom Early-Access Build.
You can make sure that this is an Eclipse related issue by compiling and running your program directly from the command line (using javac and java commands).
For ubuntu system:
Set the java 16 path in .bashrc file. Make sure only have java 16 path present in the file. If any other java path is mentioned then following command may not work.
If you want to confirm if the java version is set to 16 then execute java -version.
Then you can try directly compile your loom class through following command.
javac className.java
java className
It worked for me.
Even when you get the compilation problems go away, this might or might not print anything.
A virtual thread needs a carrier (a native thread to be executed on); and if the native thread finishes earlier then the virtual one starts, there is no such carrier; thus you get no printing. There are a couple of ways to work around that.
The simplest (just to see that this works), is to make the carrier threads sleep for a short while:
Thread.startVirtualThread(() -> {
while (true) {
System.out.println("trying " + Thread.currentThread().getName());
}
});
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
On my machine this gives enough time for some output to be generated.
Another way would be join on the carrier:
Thread t = Thread.startVirtualThread(() -> {
System.out.println("trying " + Thread.currentThread().getName());
});
t.join();
This works for demo purposes, but in real life you probably need an executor. One way to supply it would be via :
Thread.builder()
.virtual(Executors.newFixedThreadPool(1))
.task(() -> {
System.out.println("started");
})
.build()
.start();
System.out.println("done");
You can even use Executors::newVirtualThreadExecutor where the current documentation states:
Creates an Executor that starts a new virtual thread for each task
So what you could do, is something like:
ExecutorService service = Executors.newVirtualThreadExecutor();
service.execute(() -> {
System.out.println(Thread.currentThread().getId());
});
service.execute(() -> {
System.out.println(Thread.currentThread().getId());
});
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));

Java shutdown hook not launching my Process

I'm trying to give to my app self update ability.
It download an JAR from my website and save it as myapp.jar.new.
After that, I want to launch a command to delete the current version and rename the new one.
This is my code (see the notes):
public void applyUpdateAndRestart() {
Runtime rt = Runtime.getRuntime();
rt.addShutdownHook(new Thread(() -> {
try {
String updateCmd = "restart.cmd";
try (PrintStream ps = new PrintStream(new FileOutputStream(updateCmd))) {
ps.println("#echo off");
// wait for a while to the main process closes and the "myapp.jar" to be writable
ps.println("ping 127.0.0.1 -n 2 > nul");
ps.println("del /q myapp.jar.old");
ps.println("move myapp.jar myapp.jar.old");
ps.println("move myapp.jar.new myapp.jar");
ps.println("java -jar myapp.jar");
}
ProcessBuilder p = new ProcessBuilder();
p.command("cmd", "/c", updateCmd);
System.out.println("Before apply update");
p.start(); // this does not launch
System.out.println("After apply update"); // this prints!
} catch (Throwable e) {
e.printStackTrace(); // this does not occurs!
}
}));
System.exit(0);
}
Why my update.cmd does not start?
Solved with this approach:
After download my jar to new-myapp.jar, I launch it with an special argument like this: java -jar new-myapp.jar --do-update (running the new jar will unlock the current to be overwritten)
My main mehtod intercept the argument --do-update who applies the new jar to current (copy new-myapp.jar myapp.jar).
After the new jar was copied, It launches itself again using the overwritten jar (java -jar myapp.jar)
I think that Klitos comment can solve my problem too, but I solved implementing my previous approach.
On the approach of the question the problem was that the cmd /c haven't a console window allocated. Changing the command to cmd /c start solve the problem too because the start command allocate a new console window.
My idea - since you just call start() for process and finish the shutdown hook - the process dies with your main java process. Try to call Process.waitFor() to have you shutdown hook thread waiting until external process finished.
I think that you can't do it like you want. You want to remove the jar of the application but the app is running and therefore could not be removed.
My suggestion is use a launcher.cmd that look for a new.jar if it finds it remove old.jar and rename new.jar and THEN launch java -jar old.jar.

Specify Java command line options after jar execution

In an effort to make my app more OSX friendly, I am trying to set the dock name of my program to something like MyApp instead of a fully qualified class name (the default), such as myproject.mypackage.mysubpackage.myclass. Obviously, the first is much more appealing.
To do this, I use the OSX -Xdock:name command as a command line option when executing my .jar file. So to execute it, the command might look something like java -Xdock:name=MyApp -jar /mypath/myjar.jar. This works perfectly and sets the .jar's dock name to MyApp. But the issue is that this .jar will never be executed via command line and will be a double-clicked runnable .jar with a GUI display.
The only way I have thought of to set this command line option programmatically is to have a second class execute the class that actually starts the program. So something like this:
public class AppStarter {
public static void main(String[] args) {
String cmd = "java -Xdock:name=MyApp -cp myproject/mypackage/AppBuilder";
try {
Runtime runtime = Runtime.getRuntime();
runtime.exec(cmd);
} catch(IOException ex) {
//Display error message
}
}
}
public class AppBuilder {
public static void main(String[] args) {
//Start actual program and build GUI display
}
}
So here, AppStarter sets the command line options for AppBuilder, which when executed, has the dock name MyApp. The problem I see with this is that it is very tightly coupled. If for some reason the command line is inaccessible on the device or some IOException keeps getting thrown, literally nothing will happen with the program and it will be dead. There would be no way for the average computer user to recover from this.
So I'm wondering if it is possible to perhaps set these command line options after the .jar has already started executing. The old way to programmatically set the app's name has been ineffective for several OSX updates, so I'm stuck with only this command line option. Thanks for any advice.
Once the java command is executed, the command line arguments are parsed and set for the running JVM. You cannot change it any more.
This is usually handled by execution scripts (bash, etc.). If you cannot use them, you can use your approach, but the biggest disadvantage is that it will be running in a separate process.

How to create scheduler to run my script every night at 12.00- Selenium WebDriver

Currently working on Selenium WebDriver and using Java. I have a project called*Test*.
In that Project i have many Java Programs such as Login.java, Testing1.java etc.,.
The scenario is i want to run all my scripts daily morning at 12.00 a.m. Is there any possibility to create a scheduler to run my scripts automatically.
Create an testng.xml file say name as testsuite.xml.
Now follow below 2 steps:
Step 1: Create an batch file for scheduler:
use below code - modify it and paste in notepad. save the notepad in working directory as"run.bat"
set ProjectPath=C:\Selenium\Selenium_tests\DemoProject
echo %ProjectPath%
set classpath=%ProjectPath%\bin;%ProjectPath%\Lib\*
echo %classpath%
java org.testng.TestNG %ProjectPath%\testsuite.xml
a) First line is for setting project path .
b) second line is for verifying that path is set or not.
c) third
line is for setting classpath - lib folder contain all the jar
file added to project build path
d) fourth line is for verifying
whether classpath is set or not
e) fifth line is for executing
xml file having details of all test.
Step 2:
Go to control panel.
Administrative tool.
Task scheduler and create a task which will trigger run.bat file at the time you want.
It will work.
check with quartz scheduler.. http://quartz-scheduler.org/
I am currently working on a similar project where I have to check different web applications for their availability every ~5 minutes and report any errors via mail. I am also using TestNG ans the WebDriver together. I solved my "scheduling problem" by using the TimerTask class.
Here's a short code example: (Find more code examples here)
import java.util.Timer;
import java.util.TimerTask;
public class KeepMeAwake {
*
* #param args
*/
public static void main(String[] args) {
TimerTask action = new TimerTask() {
public void run() {
Beep b = Beep.getInstance();
b.beep();
}
};
Timer caretaker = new Timer();
caretaker.schedule(action, 1000, 5000);
}
}
Since it implements Runnable, you can run multiple threads with it.
Hope that helps.
If you have questions how to integrate it with your TestNG set up, just shoot.
Follow the above steps and in windows scheduler do the steps :
Creating .bat file steps
Task Scheduler in Windows > Create new Task>
'Action' settings - "Start in (Optional)" option.
Go the task properties --> Action tab --> Edit --> Fill up as below:
Action: Start a program
Program/script: path to your batch script e.g. C:\Users\beruk\bodo.bat
Add arguments (optional): <if necessary - depending on your script>
Start in (optional): Put the full path to your batch script location e.g. C:\Users\beruk\(Do not put quotes around Start In)
Then Click OK
It works for me. Good Luck!

Failing a jenkins job

I have a .Jar file that will just load data into database when it's run. I have scheduled to run this job via Jenkins. When I execute the job in Jenkins it runs the .JAR successfully. However say if there is a null pointer exception in the job and it did not complete successfully. Even then Jenkins says that job has "Passed". How do I fail the job if there is an issue during the job execution?
#Corey's solution is good. And if you don't want to write a JUnit test and support it in Jenkins, you can just do what he alluded to earlier: catch the null-pointer exception (really, just have a top-level catch in your app), and call the API to exit with a return code:
try {
myCode.call();
catch (Exception e) {
System.out.println("An exception was caught at the top level:" + e);
System.exit(-1);
}
Last time I had this problem, I decided to take a different tack and changed the program call into a junit test. Jenkins was quite happy then.
Steps I took:
1. create an empty (maven) project
2. added a single java class SmokeTest.java
3. Added test that called the method I was testing via a script
4. Create a (maven) Jenkins job to run the project
Contents of my test:
public class SmokeTest
{
private static final String OK = "OK"; //$NON-NLS-1$
#Test
public void test()
{
// Create a new instance of the Firefox driver
final WebDriver driver = new HtmlUnitDriver();
final String url = PropertyManager.getInstance().getString(PropertyManager.SMOKE_TEST_URL_BASE) + "smoke/smoketest"; //$NON-NLS-1$
AuditLog.registerEvent("Smoke test url is: " + url, this.getClass(), AuditLog.INFO); //$NON-NLS-1$
driver.get(url);
// Find the text element by its id
final WebElement databaseElement = driver.findElement(By.id("database")); //$NON-NLS-1$
final String databaseResult = databaseElement.getText();
Assert.assertEquals(SmokeTest.OK, databaseResult);
//Close the browser
driver.quit();
}
}
The most important part here is the "Assert.assertEquals" line. The result of this is pickup by jUnit and therefore jenkins
Jenkins jobs fails if the exit code is anything but zero.
System.exit(1);
Should work (or fail, to be more precise :-)

Categories