Profiling in VisualVm Using IntelliJ with Debug - java

I want to profile my test application started by IntelliJ. For profiling I useVisualVm.
I started the java tool with the parameter -J-Dorg.netbeans.profiler.separateConsole=true.
I started the application with the VM parameter -Xverify:none, otherwise VisualVM throws an error if I start profiling (Redefinition failed with error 62)
I want to profile my application before any important code has beed executed, so I tried to set a break point and start profiling in VisualVM. The problem is that VisualVm doesn't respond to any interaction while I'm waiting at my break point. Do I miss something?
In normal execution (without debugging) my program waits for input, so I can profile it without debugging. But what if a program doesn't has such "waiting points"?
My test application looks like that:
package my.visualvm.example;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
System.out.println("Starting Application: " + MainClass.class.getSimpleName());
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
double value = scanner.nextDouble();
if (value == 0d) {
break;
}
System.out.println(Powa.powaPowa(value));
}
System.out.println("Stopping Application: " + MainClass.class.getSimpleName());
}
}
Other class:
package my.visualvm.example;
final class Powa {
private Powa() {
}
static double powaPowa(double powa) {
return Math.pow(powa, 2);
}
}

Set the breakpoint to suspend the current thread only.

Related

Java (TM) Platform SE binary still running on processes

I created a console application using Java, then exported it as runnable JAR file. but when I run the JAR file the automation is finished but the "Java (TM) Platform SE binary" is still on background, I tried to put System.exit(0) and still not able to terminate the process.
I'm also trying to run this automatically in Task Scheduler in indefinitely repetition every 15 minutes, the problem is it will not run again after 15 minutes since the "Java (TM) Platform SE binary" is still in process and identified its status as running.
I'm pretty sure that all my automation task is all finished without error and not creating another threads.
Here is my code below:
public static void main(String[] args) {
String jarName = new File(Selenium.class.getProtectionDomain().getCodeSource().getLocation().getPath())
.getName();
System.out.println("Running " + jarName + " Automation");
if (args.length >= 1 && args[0].toLowerCase().equals("-run")) {
for (int i = 1; i < args.length; i++) {
String pram = args[i].replace(jarName + "_", "");
if (pram.toLowerCase().equals("all")) {
GFC.execute("Login");
GFC.execute("SwitchIntegration");
GFC.execute("BODActivate");
GFC.execute("Users");
GFC.execute("Settings");
GFC.execute("AccountingEntityRegistration");
GFC.execute("CustomizedData");
GFC.execute("BOD");
GFC.execute("BODAttributesMDM");
GFC.execute("BODAttributesTransactional");
GFC.execute("CMD");
GFC.execute("CMDAttributes");
GFC.execute("CMDDataEntry");
GFC.execute("CMDActivate");
GFC.execute("AccountingEntity");
GFC.execute("AccountingEntityMapping");
GFC.execute("JETemplates");
GFC.execute("Scenarios");
GFC.execute("Rules");
GFC.execute("RulesScript").quit();
} else {
if (!pram.equals("Login")) {
GFC.execute("Login");
}
GFC.execute(pram).quit();
}
}
if (Boolean.parseBoolean(infor.automation.utils.Properties.get("gfc.enableemailer"))) {
sendEmail();
}
}
}
Update: 3/14/2018
Worrying might my automation is creating another threads, so I decide
to create a new project and just a main class and export it as a
runnable Jar file, and it's still the same.
My JDK version is 1.8
I make a workaround or maybe a solution. I found out that the System.exit(0) on main will only close the console application, but the "Java (TM) Platform SE binary" will remain. To terminate this I extended to JFrame class to be able to override the ExitApp(). Inside the ExitApp() I add window listener and in windowClosing() I called the disposed() and System.exit(0) once more. I don't have any idea how this even works. If someone know how this works feel free to update this answer.
public class TestClass extends JFrame {
public void ExitApp() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// Dispose Java (TM) Platform SE binary.
dispose();
// Close the Java.exe I'm not sure.
System.exit(0);
}
});
}
public static void main(String[] args) {
// Close Your Application Trigger ExitApp();
System.exit(0);
}
}

How To Allow Only One .Jar Instance, And To Let It Use Args From Other Attempted Instances?

I've got a tough question, for which I will first sketch a background to make things more understandable.
Background
I have made an audioplayer in Java which can be launched with command line args, and also without. The application's .jar (made with Netbeans) is wrapped in a .exe file (made with Launch4j) so that you can open for example a mp3 file with the .exe, and then the .jar inside adopts the filepath in it's String[] args.
The problem with this approach (for now) is that if you select multiple mp3 files at once and you open them at the same time, they all get opened in seperate windows of the audioplayer. What I want however, is that all the files get opened in one single instance of the application.
What I then attempted is to let Launch4j allow only one instance of the .jar/.exe in the hopes that all the selected files would be opened in one application, this did unfortinately not work.
What I see as a solution
So I want to be able to select multiple .mp3 files in windows, and that all their filepaths get passed on as a command line arg to one single instance of the application. Or a different approach that has the same result. Does anyone know how to realize this in the actual application?
Many thanks in advance. I will try to keep looking for potential solutions/ideas as well.
--Edits--
The main method is ready to receive multiple files. I have implemented a piece of code that saves all the command line args of the application to a .txt file, and when I allow only one single instance with the Launch4j .exe file, there only appears to be one single argument in the .txt file when I try to open multiple mp3 files.
If I allow the .exe to have multiple instances, then I simply have the .jar application being launched multiple times (one time for each file I try to open).
I used java RMI (Remote Method Invokation) to make a single-instance application.
An RMI attempts to listen on a socket with a user-defined port number.
When starting the jar.
If noone serves that port, then this instance is the RMI server. Establish a GUI Window. Call an open with the main's args.
If there is already a serving application, send by RMI an open with the main's args. Then exit normally, return from main.
Code: Untested as you probably want to arrange things differently.
public interface OpenRMI extends Remote {
void open(String[] args) throws RemoteException;
}
public class SingleInstanceApp implements OpenRMI {
private static final String RMI_ENTRY = "ImJustACowLolAudioPlayer";
public static void main(String[] args) throws RemoteException,
AccessException, NotBoundException {
System.out.println("main " + Arrays.toString(args));
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
Registry registry = LocateRegistry.getRegistry();
OpenRMI openRMI;
try {
System.out.println("bind with new OpenRMI");
SingleInstanceApp app = new SingleInstanceApp();
openRMI = (OpenRMI) UnicastRemoteObject.exportObject(app, 0);
registry.bind(RMI_ENTRY, openRMI);
System.out.println("Player bound");
app.create(); // Server.
} catch (AlreadyBoundException e2) {
System.out.println("lookup as someone else bound before us");
openRMI = (OpenRMI) registry.lookup(RMI_ENTRY); // Client.
}
openRMI.open(args);
}
private void create() {
new Thread(true) { // Daemon thread, or start GUI
#Override
public void run() {
System.out.println("create " + this);
for (int i = 0; i < 10; ++i) {
Thread.sleep(1000L);
}
shutdown();
}
}
}
private void shutdown() throws RemoteException,
NotBoundException, AccessException {
System.out.println("close " + this);
Registry registry = LocateRegistry.getRegistry();
registry.unbind(RMI_ENTRY);
}
#Override
public void open(String[] args) throws RemoteException {
System.out.println("open " + this + ": " + Arrays.toString(args));
}
}
I would expect some more decent classes.
I fixed it, after some hours of programming and taking breaks inbetween
package argsbuilder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class ArgsBuilder
{
public static void main(String[] args)
{
checkIfRunning(args);
}
private static void checkIfRunning(String[] args)
{
buildFile(args);
ProcessBuilder pb = new ProcessBuilder("core.exe"); //core.exe is a .exe wrapper with the .jar audioplayer in it
try
{
Process p = pb.start();
}catch (IOException f){System.out.println(f);}
}
private static void buildFile(String[] args)
{
try
{
boolean notdone = true;
int i=0;
File f;
while(notdone)
{
f = new File("arg" + i + ".txt");
if(f.exists())
{
i++;
}
else
{
PrintStream out = new PrintStream(new FileOutputStream(new File("Folder Location" + "arg" + i + ".txt")));
System.setOut(out);
System.out.println(args[0]);
notdone = false;
}
}
}catch(Exception g){System.out.println(g);}
}}
What the above does
The above application checks if there are other argument files, and if there are it will keep generating a new name untill the name is free. It then prints the argument to that file. After it has printed the argument, it launches the audioplayer. In the audioplayer the following happens:
import javafx.embed.swing.JFXPanel;
import java.net.InetAddress;
import java.net.ServerSocket;
public class YourApp {
public static void main(String[] args)
{
try
{
socket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1}));
//Everything you need to launch the application in the try
}catch(Exception g){//Nothing in the catch}
}}
What the above does
It tries to claim a serversocket for itself. If there already is one then it does not proceed to launch the application. That way only one instance will be running at a time. (at PORT you just fill in a random integer).
Combining those 2, you can read the textfiles created by the first application and interpret them as arguments in the second application.
So how does it interpret them as arguments?
Well, I already had a timer fixed into the program, and I tell the audioplayer to look for the very first arg file (arg0.txt) in a specified folder. If it finds it it adds it to an arraylist, along with all arg+i.txt files.
It might not be the fastest way, but it surely works well.

Java Multithreading: How can i start external Java Programs, which are executing threads?

currently, i'm trying to write a programm, which should execute a seperate Java-program multiple times, but with different parameters. This executed Java-program calls a Thread-Class. Within this class, a connection to a (Game)Server is established. Once connected, the Threads sends a command to turn the connected player around every 10 milliseconds. I have 2 "solutions" for this:
The easy (working) one:
public class GeneralAgentTest {
public static void main(String [] args){
Thread thread = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15));
thread.start();
}
}
This is working correctly, but not actually my goal. I need to start several of this Threads (new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)); ) and each of this threads must be handled by a seperate process.
To do this, i wrote some code with an ProcessBuilder. This is within one class.
Second not correctly working one:
public void execute(Class class1, int a, String str, String team, String x,
String y) {
ProcessBuilder builder;
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator
+ "java";
String classpath = System.getProperty("java.class.path");
String className = class1.getCanonicalName();
builder = new ProcessBuilder(javaBin, "-cp", classpath,
className, ip, port, team, str, x, y);
try {
process[a] = builder.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("failed");
}
public void loadPlayers() {
process = new Process[4];
for (int i = 0; i < 4; i++) {
try {
execute(processes.StartProcesses.class, i,
playerCombo[i].getSelectedItem().toString(),
playerTeam[i].getText(), playerStartX[i].getText(),
playerStartY[i].getText());
} catch (Exception e) {
System.out.println("Failed to create processes for players");
e.printStackTrace();
}
}
}
These are the functions i wrote, to execute the class(es) who is/are starting the thread(s).
Following class is executed:
public class StartProcesses{
public static void main(String[] args) {
Thread t = null;
t = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15));
t.start();
JOptionPane.showMessageDialog(null, "should've started");
}
}
In my second try, the parameters which are given to the StartProcesses Class are containing some information like IP-Adresses, Portnumbers, Playerpositons and stuff like this. Anyway i was trying to execute the class with "hard" information, just to be sure it is working like in my first codepart.
The connections to the server are correctly established in both attempts, but in the first one the thread keeps working. In my second try it seems like the thread is dead after the connection is established. The process is still alive, since the connection to the server is still there.
This is a bit of code, but what i want to tell, is that the Thread is working correctly when executed manually, but it is not working correctly if i try to start the class automatically with the use of ProcessBuilders.
I really really hope you guys could understand what i am trying to say. Hopefully someone has a working solution for me.
Cheers.
EDIT: Add Code for HexagonRunner:
public class HexagonRunner extends GeneralAgent {
// Bunch of Methods
// Important Method:
#Override
protected void simulationCycle() {
turnAgent(40);
}
}
The simulationCycle() method, is the method that is going to be go through over and over again.
Since the class HexagonRunner is inherited from the class GeneralAgent, i'm going to post the relevant stuff of this class here as well:
public class GeneralAgent implements Runnable, UdpListener{
// Attributes, getters, setters, methods..
#Override
public final void run() {
// giving the worker threads the signal to start
mServerConnection.start();
mParser.start();
// waiting for the first information to be parsed, so that the
// simulation loop can run
try{
System.out.println("GeneralAgent-Run: waiting for latch");
mLogger.info("Run method: waiting for CountDownLatch");
mFirstDone.await();
}
catch(InterruptedException e){
System.out.println("GeneralAgent-Run: InterruptedException");
mLogger.info("Run method error: " + e.getMessage());
}
mLogger.info("Run method: CountDownLatch now 0, continue");
// setting the initial position
moveToPostion(mXStartCoord, mYStartCoord);
// the simulation loop
while (true){
simulationCycle();
// Shutdown if the game is over
if (mGameworld.getTime() >= 6000){ // later 6000+
System.out.println("Yeah, 50 runs completed -> Shutdown");
mLogger.info("General Agent - Time > 50, programm should terminate");
shutdown();
break;
}
// waiting for the threads to signal that they are
// ready (e.g. have new server information)
// for another round of the simulation loop
mPhaser.arriveAndAwaitAdvance();
}
}
I hope things get clearer now. I still have no idea where my code fails.
You could build somethin a lot simpler by using Executors. It' part of the comcurrent package introduced in Java 1.5. It basically works as follows:
// create a pool with 10 threads
ExecutorService executorService = Executors.newFixedThreadPool(10);
//loop as long as you need to detach your threads
for (int i = 0; i < 4; i++) {
// this actually contains the thread bit, will be executed in parallel
executorService.execute(new Runnable() {
public void run() {
// this is where your code is
new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)
}
});
}
// clean up when you're done to prevent leaks
executorService.shutdown();
That's it, much simple and you don't need to spawn different JVMs through ProcessBuilder, which is a lot slower.

Can one main thread call other main thread in java

I am looking for some more knowledge about java main method public static void main(String[] args) .When JVM call main method it creates Main thread and the whole program is get executed in this Main thread until some user thread explicitly get started in its own stack.
My question is that is it possible to start main thread from some other main method?
Its better if someone can give me some reference about main thread.
The main thread is just a concept, it's a name for the thread that starts your app, this thread is not special in any way (other than not being a daemon thread) so you can easily create new threads that are not daemons also and call another main method on them.
There isn't anything special about being the main thread, it's just the first thread to be started.
As far as my knowledgee, main thread is started by the JVM and the other threads started by the user are the sub-thread of the main thread in that thread group.
class FirstApp {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
SecondApp.main(args);
}
}).start();
Starts a new thread and calls the main method of another application. Works fine. But they run both in the same process.
However, if you want to do it as if it was executed from command line (in another (separate) process), you can also do something like this:
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
StringBuilder cmd = new StringBuilder();
cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
cmd.append(jvmArg + " ");
}
cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
cmd.append(Main2.class.getName()).append(" "); // Main2 is the main class of the second application
for (String arg : args) {
cmd.append(arg).append(" ");
}
Runtime.getRuntime().exec(cmd.toString());
// continue with your normal app code here
}
}
I took the second code mostly from How can I restart a Java application?

IDE-Style program running

My Goal
I am attempting to make a Java program in which a user can select any .class or .jar file from their computer. My program will then pop up a JInternalFrame with a JEditorPane in it as the console, capturing any console output from the user's program. When the user's program closes (calls System.exit(int status);), my program must not close along with it. My program might also have such features as a button to immediately stop the user's program and others an IDE would. My program need not compile Java code, only run .class and .jar files.
My Experience
I have made a small test version of this program wherein I got two specific files from a package and had the user click one of two buttons, each representing one of the two programs. A press of a button calls the following method:
private void run(Class runnable)
{
java.lang.reflect.Method[] m = runnable.getMethods();
boolean hasMain = false;
for (int i = 0; i < m.length; i++)
{
if (m[i].getName().equals("main") && m[i].getParameterTypes()[0].isArray() && m[i].getParameterTypes()[0].getName().contains("java.lang.String"))
try
{
Object invoke = m[i].invoke(null, (Object)globalArgs);
hasMain = true;
hub.setExtendedState(Hub.ICONIFIED);
numPrograms++;
}
catch (Throwable t)
{
java.util.logging.Logger.getLogger(Hub.class.getName()).log(java.util.logging.Level.SEVERE, null, t);
javax.swing.JOptionPane.showMessageDialog(null, "Could not run " + runnable.getName(), "Error in invocation", javax.swing.JOptionPane.ERROR_MESSAGE);
}
finally
{
break;
}
}
if (!hasMain)
javax.swing.JOptionPane.showMessageDialog(null, runnable.getName()
+ " does not have a public static main method that\nreturns void and takes in an array of Strings",
"No main method", javax.swing.JOptionPane.ERROR_MESSAGE);
}
This method successfully calls either program's main method and runs a copy of said program. However, when any of the programs this hub has started calls the System.exit(int status) command, the hub closes, too. Also, I haven't the slightest clue as to how to capture console output.
My Questions
Does anyone have any experience or advice they would be willing to share to help me make a fully-functional program that can...
Open and run a compiled Java file (remember that .jar files may have more than one class with main(String[] args) method)
Catch System.exit(int status); so that the hub program handles the internal program's exiting
Catch new java.io.PrintStream().println(Object o) and similar calls and place their output in a JEditorPane
Make a button that, when pressed, stops the internal program from running
Possibly make all JFrames the internal program uses into JInternalFrames and place them in a JDesktopPane
If you don't want the other program (which you call through it's main method) to be able to shut down the JVM you're running in, you have, as I see it, three options:
1. Using a SecurityManager
Set up the SecurityManager so that it prevents the System.exit call:
public class Test {
public static void main(String args[]) {
SecurityManager sm = System.getSecurityManager();
System.setSecurityManager(new SecurityManager() {
#Override
public void checkExit(int status) {
throw new SecurityException("Client program exited.");
}
});
try {
System.out.println("hello");
System.exit(0);
System.out.println("world");
} catch (SecurityException se) {
System.out.println(se.getMessage());
}
}
}
Prints:
hello
Client program exited.
This is probably the nicest solution. This is the way application servers prevent an arbitrary servlet from terminating the entire server.
2. Separate JVM
Run the other program in a separate JVM, using for instance ProcessBuilder
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException {
ProcessBuilder pb = new ProcessBuilder("java", "other.Program");
pb.redirectErrorStream();
Process p = pb.start();
InputStream is = p.getInputStream();
int ch;
while ((ch = is.read()) != -1)
System.out.print((char) ch);
is.close();
System.out.println("Client program done.");
}
}
3. Use shutdown hooks instead
Don't disallow the termination of the JVM, but instead add shutdown-hooks that cleans up the "hub" and exits gracefully. (This option probably only makes sense if your running one "external" program at a time.)
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Uninitializing hub...");
System.out.println("Exiting gracefully.");
}
});
// Run client program
System.out.println("Running... running... running...");
System.exit(0);
}
}
Prints:
Running... running... running...
Uninitializing hub...
Exiting gracefully.

Categories