Is it possible to compile and run java without using any shell? - java

This question just popped to my mind.
To compile java, we need to use the $JAVA_HOME/bin/javac file and pass to it the java files that needs to be compiled.
I was wondering if it is possible to execute javac file without using the bash/shell.
Or use any other programming languages to execute the javac file directly?

Yes, it is possible.
#include <unistd.h>
int main(void)
{
execl( "/path/javac","javac", "/path/to/program.java", NULL );
return 0;
}
That C program will execute the compiler and compile program.java without using a shell. Just run it also without using a shell and you have run the compiler without a shell.
It is not a very useful program, it always compiles the same single file. But it is possible to modify it to read a file with a list of files to compile. Which is actually what IDEs do. And that is another way of running javac without a shell.
As for running the compiled java program the same principle applies. Create a program which runs the java interpreter.

It is not possible to use javac without, on some level, executing it as a shell command, because by its nature it is a command line program. This means that it can be executed from any programming language that can execute native shell commands.
What most people do after learning how javac works by executing it manually from a shell is configure their IDE to execute javac with the correct arguments when developing, and configure a build technology such as maven or ant to execute javac to produce their deployable application package.

Related

What is the mechanism of java and javac?

I just picked up my Ubuntu machine after a long time for some java related work and found that I have java already installed but not javac.
I made a Test.java file with a main method and a simple print statement. I wrote this in my terminal:
java Test.java
I expected that without javac this shouldn't compile and run but it printed the output on my console. I then installed a JDK to enable the javac and ran this:
javac Test.java
This created a Test.class file. Still to run the Test class I need to type java Test.java and on typing java Test it throws java.lang.NoClassDefFoundError.
Can someone please explain to me what's happening in the background of these commands?
Edit:
Here are the contents of my Test.java:
package Learning;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World!");
}
}
What you experience here is a new feature, added for Java 11:
In Java SE 11, you get the option to launch a single source code file directly, without intermediate compilation. Just for your convenience, so that newbies like you don't have to run javac + java (of course, leaving them confused why that is).
Quoted from here. For more details, see the corresponding JEP 330.
So: if you have a single self-contained .java file ... then the java binary recognizes that, compiles it, and directly runs it (when using Java 11 or newer).
But keep in mind: it is just that, a way to quickly run a single class. It isn't meant to replace the "real" way of doing things.
In general, you still use javac first, and then java. Or, more real world: you use a built system where you describe what to build, and then the build system invokes javac for you behind the covers.
GhostCat's answer is good, but here are a few additions taken from a longer post about this same behavior.
Can someone please explain to me what's happening in the background of these commands?
What you ran into – where you can use "java" (not "javac") to
compile and run a program in one command – JEP 330: Launch Single-File Source-Code Programs –
was designed to make it easier for "early stages of learning Java, and when writing small utility programs".
It's definitely
not meant to replace anything – use it if convenient, but nothing changes with the normal steps of "compile to .class file" and "run JVM using .class files or JARs".
There's some good info in the JEP 330 link, but also in the java command itself, namely that one option (among four total) is to provide a single filename (which is what you did)
To launch a single source-file program:
java [options] source-file [args ...]
Further, there's a nice summary in Using Source-File Mode to Launch Single-File Source-Code Programs:
In source-file mode, the effect is as though the source file is compiled into memory, and the first class found in the source file is executed. Any arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed.

Jython Installation and Running (Beginner Issues)

I am having some serious trouble installing and running Jython. I am completely new to how jython runs, so I am pretty lost. I have downloaded Jython 2.5.3 and java jre 1.8.0_25. I believe I have succesfully run the jython.jar file using this command in cmd:
C:\java\jre1.8.0_25\bin\java -jar C:\jython2.5.3\jython.jar
I have beginner-intermediate (closer to beginner) knowledge of programming in jython, but that is on a computer with jython already installed. My main problem is being able to run jython so I can see the actual function/program area where you would type out your functions then run them. I appreciate any help someone can give.
That command is exactly how you run Jython, and without providing any additional arguments, the Jython interpreter will start (where you can type out functions and run them).
If you want to run Jython with a single command, there should be a jython.bat file located somewhere under the Jython installation directory. Jython does not have a true executable because it is run through Java. The jython.bat file is the closest you'll get to an executable because it is a batch script which runs the jython.jar file using a command nearly identical to yours with Java. jython.bat should be located at one of the following locations:
C:\jython2.5.3\jython.bat
C:\jython2.5.3\bin\jython.bat
NOTE: The jython.bat file requires a standard Java installation.

How do I run a Java program on Terminal (Mac)?

I am new to Java (as of today!) and am trying to run a very simple program in terminal. Normally, when I run a python (still pretty new) program in Terminal I would simple type in "python name.py" in to terminal and it would run. When I type "Java name.java" it does absolutely nothing.
I opened TextWrangler and selected "Run in Terminal" and it returned this error:
"This file doesn't appear to contain a valid 'shebang' line (application error code: 13304)"
My program is named "hello.java" and it contains the code below.
What am I doing wrong?
System.out.println("Hello!");
Open the terminal, go to the directory where the file is located and do this:
javac -classpath . name.java // compile the code
java name // run the program
Of course, both javac and java must be available in the operating system's PATH variable, but in a Mac that's already configured.
Type
javac helloworld.java
java helloworld
The first line calls the compiler and compiles it in the current directory
then the next line runs it
"Run in terminal" attempts to run the software as an interpreted script. On UNIX-like systems (meaning almost everything except Windows), a shebang line is used to indicate, what interpreter is to be used. It consists of the characters #! followed by the command to invoke the interpreter (e.g. #!/usr/bin/python or #!/usr/bin/ruby). However, Java is not (only) interpreted.
java only runs compiled Java bytecode, so it does not work on source files
Instead, head over to the terminal yourself, compile the code with javac and run the resulting bytecode (the .class files) with java:
javac the_file_name.java
java the_class_name
where the_file_name.java is the file containing main(...) and the_class_name is the name of the class containing main(...) (this should usually be the same as the_file_name)

Making a "macro" command to run a program

I have a Main.java file and I want to run the program passing it test.txt
I know in command line I can write javac Main.java
After compiling I can write java Main test.txt and this will accomplish running the file and passing test.txt
If I wanted instead to be able to just write main test.txt and have that trigger my Main.class file to run is that possible and if so how?
(Edit: Based on your comment, let me expand to add a couple more situations)
If your goal is to have someone else run your program who does not have Java installed, and you do not wish to have them install a Java runtime environment before running your app, what you need is a program that converts the .class or .jar files into a native executable for the platform you are using. How to do this has been covered in other questions, eg: Compiling a java program into an executable . Essentially, you use a program like JCG (GNU Compiler for Java) or Excelsior JET (a commercial product) to expand the byte code into full native code with a mini-JRE built in.
If your goal is to save typing, there are a number of strategies. Others have suggested alias commands, which work well on linux.
A slightly more portable option that you could ship with your program would be a shell script. Granted, shell scripts only run on linux or other OS's with shell script interpreters installed.
Here is an example shell script. You paste this into a text editor and save it as main with no extensio. The $1 passes the parameter argument fyi.
#!/bin/sh
java Main $1
presuming you name your shell script just "main" with no extension, you could call main test.txt to execute your program now.
If you are on Windows, you might want to create a windows shortcut, and point the shortcut to "java Main test.text", using the full paths if necessary (if the paths are not already set). Of course, this does not make the parameter easy to change every time you run it, you would have to edit the shortcut.
add an alias
e.g. under a mac edit your .bash_profile with the following line
alias main='java main'
don't forget to open a new console to see your alias working
Depends on your operating system. On Linux with the bash shell, for instance, you can set up an alias to expand your main into java -cp myjar.jar main.
Linux can also be configured to 'understand' Java class flies as a binary format directly see here (linux kernel documentation).
If you're on windows, you'll have to wait for answer from someone with more knowledge about that than I.
Good luck!

creating 100% standalone executable jar that doesn't require the java command

so apparently if you create an executable jar, in order to run it you still need the java command:
java -jar something.jar
but what if I just want it to run without the java command, so just directly from the command line
something.jar
is there a way to export my java app in eclipse in order to accomplish such
On Unix systems you can append the jar file at the end of an executable script.
On Windows you have to create a batch file.
For instance in Unix:
$cat HelloWorld.java
public class HelloWorld {
public static void main( String ... args ) {
System.out.println("Hola mundo!");
}
}
$cat M.mf
Main-Class: HelloWorld
$cat hello
#!/bin/sh
exec java -jar $0 "$#"
$javac HelloWorld.java
$jar -cmf M.mf hello.jar HelloWorld.class
$cat hello.jar >> hello
$chmod +x hello
$./hello
Hola mundo!
In windows you have to create a batch file like:
::hello.cmd
javaw -jar hello.jar
Which has the same effect.
On Windows and OSX you can double click on the jar to run it, I'm pretty sure you may add a trigger on Linux too.
I hope this help
Excelsior JET - http://www.excelsior-usa.com/jet.html - claims to compile to native code and bring its own runtime support, so it does not require an existing JVM. Commercial product.
I have not tried it myself, but they have spent quite a bit of effort over the years to market JET as a great deployment method for precompiled binaries.
Also note that if you have an executable/runnable jar which works fine with "java -jar someting.jar" and you just want to be able to invoke it in a more convenient way, this is the job of the program accepting your command and launching the java command.
For Linux you can frequently add an alias saying that "something" expands to "java -jar something.jar", and some command interpreters allow for saying that all commands ending with jars should be executed specially. The exact details depend on which shell (command line interpreter) you are using.
What you need is a tool called 'Java Executable Wrapper'.You can use it to Pack all your class files to a Single Executable Package.
The One i recomment is launch4j,you can download it from sourceforge launch4j.sourceforge.net
Launch4J can be used to create standalone Executables (.exe) from a jar file for windows Environment.
The thing is, that Java gets interpreted by the JVM, so you'll at least need to ship it with your app.
To be a little more specific about this, Java gets kind of compiled to byte-code so it can be interpreted faster. But the Byte-Code can't run without the JVM. This is the nice side of Java: You don't need to recompile your Apps to run on other platforms like Linux or OS X, the JVM takes care of that (as it is written in native code and is recompiled for those platforms).
There are some compilers out there which can convert your Java code to something native like C which can then be executed without the JVM. But this isn't the idea behind Java and most of those tools suck at what they do.
If you want your App to run without any interpreter, you'll need to use a compiled language like C or C++
Java program runs on a JVM, for the first question I don't think there's a compiler that can do the job well. For the second question since a jar file is not an executable per se, there must be some sort of settings in the target machine, "executing" a jar file without providing the java command is a matter of convenience for the user. On Windows every file extension has a program associated with it, so .doc documents have (usually) Word as the program associated -that setting is set by the office installer, the java runtime also sets the setting for .jar files when you install it, but behind the scenes, java command will be used by the system. So the short answer to the second question is: depends on the target machine.

Categories

Resources