Since Java 6, you can compile and run a Java compilation unit defined as a String or a File using standard APIs in the SDK (a compilation unit is basically everything that goes inside a .java file - package, imports, classes/interfaces/enumerations), take a look at this example. You can't run an arbitrary Java snippet like the one in your question, though.
If at all possible, it'd be a better idea to embed a different scripting language that allows you to run snippets of code from a Java program - for example, JavaScript, Groovy, MVEL, BeanShell, etc.
Answer from Óscar López on Stack OverflowVideos
Since Java 6, you can compile and run a Java compilation unit defined as a String or a File using standard APIs in the SDK (a compilation unit is basically everything that goes inside a .java file - package, imports, classes/interfaces/enumerations), take a look at this example. You can't run an arbitrary Java snippet like the one in your question, though.
If at all possible, it'd be a better idea to embed a different scripting language that allows you to run snippets of code from a Java program - for example, JavaScript, Groovy, MVEL, BeanShell, etc.
If you turn it into a full-blown source file, you can feed it to the java compiler programmatically, but last time I checked that was only available if you had the java SDK installed on your machine; it was not available on machines with the client distribution of Java. Of course, this may have changed since then. Look at package com.sun.tools.javac and you will find the java compiler API there.
You're trying to execute "C:/". You'll want to execute something like:
"javaw.exe d:\\somejavaprogram\\program.jar"
Notice the path separators.
I'm assuming this is for an ad-hoc project, rather than something large. However, for best practice running external programs from code:
- Don't hardcode the executable location, unless you're certain it will never change
- Look up directories like %windir% using System.getenv
- Don't assume programs like javaw.exe are in the search path: check them first, or allow the user to specify a location
- Make sure you're taking spaces into account:
"cmd /c start " + myProgwill not work if myProg is"my program.jar".
You can either launch another JVM (as described in detail in other answers). But that is not a solution i would prefer.
Reasons are:
- calling a native program from java is "dirty" (and sometimes crashes your own VM)
- you need to know the path to the external JVM (modern JVMs don't set JAVA_HOME anymore)
- you have no control on the other program
Main reason to do it anyway is, that the other application has no control over your part of the program either. And more importantly there's no trouble with unresponsive system threads like the AWT-Thread if the other application doesn't know its threading 101.
But! You can achieve more control and similar behaviour by using an elementary plugin technique. I.e. just call "a known interface method" the other application has to implement. (in this case the "main" method).
Only it's not quite as easy as it sounds to pull this off.
- you have to dynamically include required jars at runtime (or include them in the classpath for your application)
- you have to put the plugin in a sandbox that prevents compromising critical classes to the other application
And this calls for a customized classloader. But be warned - there are some well hidden pitfalls in implementing that. On the other hand it's a great exercise.
So, take your pick: either quick and dirty or hard but rewarding.
You could pass a Runnable:
public static long measureExecution(Runnable code) {
long start = System.nanoTime();
code.run();
long time = System.nanoTime() - start;
return time;
}
At the place where you call the method, use an anonymous inner class to wrap the code you want to measure:
long time = measureExecution(new Runnable() {
@Override
public void run() {
System.out.println("Do something");
}
});
(If you were using Java 8, you could use a lambda expression instead of an anonymous inner class, which would make the code shorter and easier to read).
You can use OpenHFT/Java-Runtime-Compiler:
https://github.com/OpenHFT/Java-Runtime-Compiler
Also, you can use ToolProvider class (Compiler API), since java 1.6:
private Path compileJavaFile(Path javaFile, String className) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, javaFile.toFile().getAbsolutePath());
return javaFile.getParent().resolve(className);
}
tl;dr
In modern Java, as a convenience to beginner Java students, the java app will graciously compile, and then run, a .java file.
Think of it as java app detecting a source-code file, then sub-contracting the compilation work out to javac app, caching the compiled class in memory, and lastly continuing onwards to run the newly compiled class.
Details
A JDK comes bundled with a few dozen tools. A couple of these are crucial:
- javac — Compiles
.javafile of source code text into.classfile of bytecode. - java — Execute that
.classfile by launching a JVM.
The process steps are:
- You write Java source code in a
.javafile, including amainmethod inside aclassdefinition. - You submit that file to a compiler, such as the javac app bundled with every JDK.
- The compiler outputs a
.classfile. - You execute (run) the
mainmethod by launching the java app bundled with every JDK.
You can skip some steps.
- Compile and run a single file:
As of Java 11, you can point the java app to a.javafile. The java app will automatically compile first, as if javac were called on your behalf. Then the java app will go on to run the newly compiled class.- No
.classfile is written to storage. The compiled class is cached in memory. - See JEP 330: Launch Single-File Source-Code Programs for all the details.
- This behavior is what you noted: However,
java HelloWorld.javawas executed properly without making HelloWorld.class.
- No
- Simplified
main
As a preview feature in Java 21, you can:- Write your
javafile without declaring a class. Just write themainmethod alone, with nothing around it. - Drop the
public staticfrom yourmainmethod declaration. - See JEP 445: Unnamed Classes and Instance Main Methods (Preview) for details.
- Write your
Motivation
The Java team is making concerted efforts to ease the way for beginning Java programmers, to smooth over the initial speed bumps. They are trying to mask some of the elaborate ceremony, and make the tooling more friendly and accommodating.
The underlying structures and features of Java are still in place. This is not a “dumbing-down” of Java. These efforts are just attempts at making reasonable accommodations for beginners.
Hello World
Combining these features, getting started with a Hello World app is a simple as writing the following in a HelloWorld.java file:
void main() {
System.out.println("Hello, World!");
}
… and then on the command-line calling:
java HelloWorld.java
Result on the console:
Hello, World!
That is a vast reduction in labor and confusion for a brand-new student of Java.
jshell
By the way… Another piece of making Java easier to use is jshell, a REPL for Java.
Both beginners and pros find jshell handy for running short bits of Java with immediate feedback.
BlueJ
Another useful tool for beginners is BlueJ, an IDE designed for students.
As mentioned in the JEP-330, for your example
java HelloWorld.java
is informally equivalent to
javac -d <memory> HelloWorld.java
java -cp <memory> hello.World
javac is the Java compiler. java is the JVM and what you use to execute a Java program. You do not execute .java files, they are just source files.
Presumably there is .jar somewhere (or a directory containing .class files) that is the product of building it in Eclipse:
java/src/com/mypackage/Main.java java/classes/com/mypackage/Main.class java/lib/mypackage.jar
From directory java execute:
java -cp lib/mypackage.jar Main arg1 arg2
A very general command prompt how to for java is
javac mainjava.java
java mainjava
You'll very often see people doing
javac *.java
java mainjava
As for the subclass problem that's probably occurring because a path is missing from your class path, the -c flag I believe is used to set that.