How can I start a 'main' in a new process in Java?

steps to start a small business
how to start a business plan
how to start a business from scratch
how to start a business online
starting a business for dummies
how to start a small business at home
how to start a business without money
starting a business ideas

The question is rather simple. How can I start a main method in another java process? Now I do it like this:

startOptions = new String[] {"java", "-jar", "serverstart.jar"};
new ProcessBuilder(startOptions).start();

But they asked me to do it not with an external .jar file. The serverstart.jar obviously has a main method, but it it possible to call that main method in another process, without calling the .jar file?

I'm thinking of something like this:

new ProcessBuilder(ServerStart.main(startOptions)).start();

But I don't know if anything like that exists.

Kind regards,

Assuming a new thread with a new classloader is not enough (I would vote for this solution though), I understand you need to create a distinct process that invokes a main method in a class without having that declared as "jar main method" in the manifest file -- since you don't have a distinct serverstart.jar anymore.

In this case, you can simply call java -cp $yourClassPath your.package.ServerStart, as you would do for running any java application when you don't have (or don't want to use) the manifest Main-Class.

The Complete, 12-Step Guide to Starting a Business, Starting a business involves planning, making key financial decisions, and completing a series of legal activities. Scroll down to learn about each step. How to Start a Business: A Step-by-Step Guide You want to make sure you prepare thoroughly before starting a business, but realize that things will almost certainly Conducting in-depth market research on your field and the demographics of your potential clientele is an important part Before

Creating a new "java" process from java is not possible since two processes can't share one JVM. (See this question and the accepted answer).


If you can live with creating a new Thread instead of a Process you can do it with a custom ClassLoader. It is as close you can get to a new process. All static and final fields will be reinitialized!

Also note that the "ServerStart class (for the example below) must be in the class path of the current executing JVM):

public static void main(String args[]) throws Exception {
    // start the server
    start("ServerStart", "arg1", "arg2");
}

private static void start(final String classToStart, final String... args) {

    // start a new thread
    new Thread(new Runnable() {
        public void run() {
            try {
                // create the custom class loader
                ClassLoader cl = new CustomClassLoader();

                // load the class
                Class<?> clazz = cl.loadClass(classToStart);

                // get the main method
                Method main = clazz.getMethod("main", args.getClass());

                // and invoke it
                main.invoke(null, (Object) args);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}

And this is the custom class loader:

private static class CustomClassLoader extends URLClassLoader {
    public CustomClassLoader() {
        super(new URL[0]);
    }

    protected java.lang.Class<?> findClass(String name) 
    throws ClassNotFoundException {
        try{
            String c = name.replace('.', File.separatorChar) +".class";
            URL u = ClassLoader.getSystemResource(c);
            String classPath = ((String) u.getFile()).substring(1);
            File f = new File(classPath);

            FileInputStream fis = new FileInputStream(f);
            DataInputStream dis = new DataInputStream(fis);

            byte buff[] = new byte[(int) f.length()];
            dis.readFully(buff);
            dis.close();

            return defineClass(name, buff, 0, buff.length, (CodeSource) null);

        } catch(Exception e){
            throw new ClassNotFoundException(e.getMessage(), e);
        }
    }
}

Starting a Business, Starting your own business can be thrilling and exciting, but also daunting. If you are considering launching a startup, these 35 invaluable tips  Setting Out the Basics 1. Choose an idea. It might be a product you've always wanted to make, or a service you feel people need. 2. Define your goals. Do you want financial independence, eventually selling your business to the highest bidder? 3. Create a working name. You could even do this before

I would suggest invoking a shellscript from java and using it to start the new process (if you cant live with just another thread at all).

10 Steps to Start Your Business, The first steps to starting a business are surprisingly simple. Here's how to get through the administrative hurdles faster than you think. You can start a new video meeting from your computer or mobile device with Google Meet. Before you begin For G Suite users: Sign into a G Suite account. For non-G&nbsp;Suite users (us

I'll answer here how to create multi process application without spring :). With spring you can do this by xml config. Multithread is another story, this is multi-process

Create a JavaProces class as seen below. You can store a counterparter XML/JSON of this class in your environment. Then start your process with Runtime.getRuntime().exec(processRunnerString);,

You should first find java.exe , vm args, then set -classpath then mainClass and args respectively.

Finally you will have something like java JRE\java.exe -classpath .;*;lib* AClass arg1 - Dprop=val

You can use JMX to communicate with other process.

import java.util.Dictionary;
import java.util.List;

public class JavaProcess {

    private String mainClass;
    private Dictionary<String, String> vmParameters;
    private List<String> classPath;
    private List<String> mainArgs;

    public String getMainClass() {
        return mainClass;
    }

    public void setMainClass(String mainClass) {
        this.mainClass = mainClass;
    }

    public Dictionary<String, String> getVmParameters() {
        return vmParameters;
    }

    public void setVmParameters(Dictionary<String, String> vmParameters) {
        this.vmParameters = vmParameters;
    }

    public List<String> getClassPath() {
        return classPath;
    }

    public void setClassPath(List<String> classPath) {
        this.classPath = classPath;
    }

    public List<String> getMainArgs() {
        return mainArgs;
    }

    public void setMainArgs(List<String> mainArgs) {
        this.mainArgs = mainArgs;
    }

}

MainRunner Application, you can gather JavaProcess instance from a configuration file. I just created a dummy Process here and in case of error I stop it from callback of the process.

    //process
    JavaProcess jp = new JavaProcess();

    //java class
    jp.setMainClass("com.hmg.vidapter.run.DriverLauncher");

    //main args[]
    List<String> mainArgsList = new ArrayList<String>();
    mainArgsList.add("ABC1 ARG2 ARG3 ARGN");
    jp.setMainArgs(mainArgsList);

    //-classpath
    List<String> classPath = new ArrayList<String>();
    classPath.add("*");
    classPath.add("libs\\*");
    classPath.add("repo\\*");
    jp.setClassPath(classPath);

    //-Dvm args.
    Dictionary<String, String> vmArgs = new Hashtable<String, String>();
    vmArgs.put("-Dcom.sun.management.jmxremote", "");
    vmArgs.put("-Dcom.sun.management.jmxremote.authenticate=false", "");
    vmArgs.put("-Dcom.sun.management.jmxremote.port=1453", "");
    vmArgs.put("-Dcom.sun.management.jmxremote.ssl=false", "");
    jp.setVmParameters(vmArgs);

    String params = JSONUtils.convertToJSON(jp);
    System.out.println(params);

    StringBuilder sb = new StringBuilder("\"" + getJavaExecutablePath()+ "\"");

    sb.append(" ");

    Enumeration<String> vmaEnum = vmArgs.keys();
    while (vmaEnum.hasMoreElements()) {
        String key = vmaEnum.nextElement();
        sb.append(key + " ");
        String val=vmArgs.get(key);
        if(val!=null && !val.isEmpty())
        {
            sb.append(val + " ");
        }
    }

    sb.append(" -classpath ");
    List<String> cps = jp.getClassPath();
    for (String cp : cps) {
        sb.append(cp+";");
    }
    sb.append(" ");             
    sb.append(jp.getMainClass());
    sb.append(" ");

    List<String> mainArgs = jp.getMainArgs();
    for (String ma : mainArgs) {
        sb.append(ma+" ");
    }

    System.out.println(sb.toString());
    Process p = Runtime.getRuntime().exec(sb.toString());

    //write output
    InputStreamReader isrO = new InputStreamReader(p.getInputStream());
    BufferedReader brO = new BufferedReader(isrO);
    String callBackO = brO.readLine();
    if (callBackO!=null)
    {
        System.out.println("Application Output: " + callBackO);         
    }

    //write errput
    InputStreamReader isr = new InputStreamReader(p.getErrorStream());
    BufferedReader br = new BufferedReader(isr);
    String callBack = br.readLine();
    if (callBack!=null)
    {
        System.err.println("Application Error: "+ callBack);
        //you can do whatever you want if you don't wanna stop it
        p.destroyForcibly();
    }

Determine location of java.exe from java.home env. variable

private static String getJavaExecutablePath(){
        String javaHome = System.getProperty("java.home");
        File f = new File(javaHome);
        f = new File(f, "bin");
        f = new File(f, "java.exe");
        return f.getAbsolutePath();
    }

The Complete 35-Step Guide For Entrepreneurs Starting A Business, A start up business can be established with little to no money and have the potential to scale. Laurie Davis started the dating website eFlirt.com  In the Zoom client, click Meetings . Under the Upcoming tab, select the meeting you want to start. Additional options will appear. Click Start .

You can do this using Reflection (java.lang.reflect package).

public static void main(String[] args) throws Exception {
    Class c = Class.forName("ServerStart");
    Class[] argTypes = { args.getClass() };
    Method m = c.getMethod("main", argTypes);
    Object passedArgv[] = { args };
    m.invoke(null, passedArgv);
}

How to Start a Small Business in a Few Hours, This step is not supposed to dissuade you from starting your own business. Rather, it's here to get you thinking and planning. In order to start a successful business  To start a business without money, make sure to keep your current job so you’ll still have income. Start working on a business plan that includes what you will sell, what your costs will be, and what sort of staff you should hire. Then, do some research and test out your ideas on a small scale, like at a fundraiser or at an event.

25 Businesses You Can Start for Less Than $100, Bonus: If you can't wait to get started check out my Ultimate Guide to Starting an Online Business. How to Start Your Own Business in 5 Steps. Step 1: Find a  Make a difference by starting your petition today. Change.org is a free, easy to use platform that connects you to a community of over 180 million passionate members.

8 Steps to Starting Your Own Business,

How to Start Your Own Business: the Ultimate 5 Step Guide,

Comments
  • Would it help, or be permitted, to duplicate current classpath as an argument in your ProcessBuilder? .. System.getProperty("java.class.path")
  • I don't know, how do I have to do it then?
  • then you will have classpath with you you just need to pass it to -cp and load java
  • I did it like his: startOptions = new String[] {"java", "-cp", System.getProperty("user.dir"), "target.classes." + ServerStart.class.getName()}; But it gives me java.lang.NoClassDefFoundError: target/classes/sample/plugin/hello_maven_plugin/ ServerStart (wrong name: sample/plugin/hello_maven_plugin/ServerStart) So I guess I'm in the right directory, bu he can't find the right class I guess.
  • Assuming your user.dir is the maven project root directory, target/classes should NOT be used as package prefix, but instead added to the file system path: new String[] {"java", "-cp", System.getProperty("user.dir") + "/target/classes", ServerStart.class.getName()}
  • Nice! I'm in the right class now, but now I have the problem that he can't find a specified .jar file. In my ServerStart, he starts a server imported from hsqldb, but he can't find it. Caused by: java.lang.ClassNotFoundException: org.hsqldb.Server
  • However, it's not a good idea to rely on running the application from the maven project root dir, so I think a better solution would be to simply reuse the classpath of the current process (and use the current directory as fall-back): new String[] {"java", "-cp", System.getProperty("java.class.path", "."), ServerStart.class.getName()}
  • I wrote my previous comment before I saw your reply, but it seems to address this latest issue that you mentioned also, as the FULL classpath of the current process will be used.
  • Creating a new "java" process from java is not possible since two processes can't share one JVM. -- maybe I'm missing something, but I don't see sharing one JVM as a requirement here.
  • @Costi, No, but ServerStart.main(startOptions) indicates that there is is a posibility that he would like to call the main-method from within the JVM.
  • Sure, but that's simply a method call, it has nothing to do with any new process.
  • Wouldn't you be better off subclassing URLClassLoader rather than ClassLoader? Then you'd be able to handle Jars and class directories without any effort.
  • @aioobe: I got it now, the ProcessBuilder in conjuction with a main() method call does indeed create this confusion, so dacwe was right to clarify this from the very beginning.
  • This will not start a new process and might not reinitialize static and final variables.
  • won't work. You need a custom ClassLoader to reinitialize all variables.