Easy command line Java compile - java

So I have to send a java project to someone outside our company who has no experience with java and they need to compile it. Is there an easy way to do it on the windows command line that does not require writing out lists of the files?
Personally I think javac should be smart enough to handle
javac *
when in the folder just under the root of the package hierarchy. Is there anything in this ballpark?
Edit: The source folder structure is complex and the is no single entry class so some of the ideas mentioned so far won't work. Thanks though! Think 9 levels deep with code on many levels.

From the folder that represents the base of your package hierarchy, assuming your entry point class is called Main, in a package called app,
javac -classpath . app/Main.java
should generate the correct class definitions. The compiler will ferret out the dependencies and compile whatever other classes are needed. The class files will appear in the same directory as their source files.
If, as you say, you have 'more than one entry' class, you will have to at least identify all those top level classes from the dependency hierarchy, which can be listed as further params to javac, specifying the packages as they occur. Like so, assuming you also need to start with other.Entry
javac -classpath . app/Main.java other/Entry.java
Note that you will still have to figure out which of your classes are tops of independent dependency hierarchies, whether you are creating an ant script or doing it this way.

javac BaseProgram.java will compile BaseProgram.java from the current directory, and all classes it references that are available in source code, in the same directory tree.
If BaseProgram references Class1 and Class2, and they are available in Class1.java and Class2.java in the same directory, then they too will get compiled. Likewise if they are in a package, and the package directory is available, they will be compiled.

Provide them with an Ant script that does the build with the correct libraries on the classpath, etc. The script can also do other tasks such as building JARs, etc.
This requires that that person downloads and installs Ant, but that is not hard. (And there is nothing to stop you from providing them with an appropriate Ant distro to install. Or even sending them a distro ZIP file that has a copy of Ant "preinstalled" in the tree.)
Providing an Ant script means that you avoid them falling into Java newbie traps such as forgetting to set the classpath, being in the wrong directory, forgetting to recompile dependent files and so on. Plus, it is more "professional".

You can build a file listing all the classes you want to compile (extracted from the javac man page) -
Example - Two Arg Files
You can create two argument files -- one for the javac options and
the other for the source file-
names: (Notice the following lists have no line-continuation
characters.)
Create a file named options containing:
-d classes
-g
-sourcepath /java/pubs/ws/1.3/src/share/classes
Create a file named classes containing:
MyClass1.java
MyClass2.java
MyClass3.java
You would then run javac with:
% javac #options #classes
Or you can use *.java on the command line e.g.
javac greetings/*.java
(Again from man javac)
Or why don't you just compile the source into a jar that your customer can run using their JRE - especially considering they are not Java savvy?

A simple way would be by using:
javac *.java.

Related

Java command to run the main class

I have been away from Java stuff for quite sometime, need some help about basic stuff.
I have the following project structure :
There are no manifest files etc, its just a raw folder structure.
I wanted to know command to compile these java classes from root folder Data Structures - Java and command to execute compiled classes.
I did try
javac -d build com.codesuman.datastructures.Main
This worked first time but failed in next attempt.
Thanks in advance.
I don't see how that could work, even a single time :
javac -d build com.codesuman.datastructures.Main
In javac, the last argument is "source files". It has to specify location of java source to compile in terms of filesystem location : that is file or directory.
But that com.codesuman.datastructures refers to a java package. Something like that is expected : com/codesuman/datastructures/Main.java.
So, to compile that class in the build directory, do that :
javac -d build com/codesuman/datastructures/Main.java
But if Main.java relies on other classes, which looks possible according to your snapshot, you also need to compile these classes.
So a more idiomatic approach in this case is :
javac -d build com/codesuman/datastructures/*.java
But beware the subfolders are not compiled.
Main class seems to be inside linear folder
This should do the job javac -d build com.codesuman.datastructures.linear.Main

Difference between sourcepath and just specifying the source file?

What is the point of the javac -sourcepath option?
Say you have a file Ball.java, and file Eight.java, there seems to be no difference between running:
javac Eight.java lib/pool/Ball.java
and
javac Eight.java -sourcepath lib
The classpath makes sense to me as it means you just need to distribute class files to developers who won't need to mess with the source, but I would think you're only likely to have/need the source if it's your own/an internal project so can't understand why it's needed.
Do people have large repositories of source code instead of classes?
From further testing I've confirmed that -sourcepath doesn't even take the last modified date of the source into account like the classpath, so couldn't even conceivably save time during building. As when using -classpath, this will build the .class file if it doesn't exist and the source does, or if the .java file is newer than the .class file, whereas any source files on the sourcepath will be built again irregardless of how new they are. And when -sourcepath and -classpath are both specified then it takes the action of the classpath to only rebuild if the source files are newer, so specifying the sourcepath and classpath appears to be completely pointless.
I've also tested to make sure that -sourcepath and -classpath both only build the necessary source files needed for resolution.
The only upside from -sourcepath over specifying the specific .java files I can find is that sourcepath just has to have a directory specified, and any jar or zip files are automatically extracted.
So is the point of -sourcepath due to laziness (not wanting to extract & specify all the source files)?
And is there any upside to using -sourcepath over -classpath? Since they appear to do the same thing but classpath performs it better by saving time when the source doesn't need rebuilding.
The sourcepath is used to locate .java files for classes referenced in the files you asked to compile (Eight.java in your example) for which no .class file exists. The compiler will automatically compile those too. I'm not sure if it compares the modified-time of the .java and corresponding .class file and recompiles the .java if it is newer, but I think it does.
I've found from further colleagues in development that they would generally use this during development if they want to build part of a project or subproject. Instead of building everything from scratch (which could take hours), they instead simply want to build a few projects, then they can specify other directories of the whole project in -sourcepath so that this can resolve classes. This means it can automatically find what dependencies it needs and build these as and when they are needed.
I've also been informed that this can be helpful during maven builds since the order of dependency gathering can be very unorganised. Instead of having missing dependencies because the jars aren't there at time of building, you can specify the entire code tree as the sourcepath. Although I imagine this isn't the best advice, it's helpful when somebody is having problems building.

Compiling Java package throws errors for external Jars

Pretty basic problem here. So I have a Java package that I have created that has three classes (one has the main method). I am trying to use a few Apache Jars, and have added these to my build path in Eclipse. However Eclipse wont let me build and run it properly, so I am trying the command line. I have added the env var CLASSPATH and pointed it to my lib directory which hold the Apache Jars. However, when I try to use javac I get a bunch of errors:
package org.apache.xmlrpc does not exist
import org.apache.xmlrpc.client.XmlRpcClient;
I was reading the man page for javac and it said that:
If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory.
So I tried copying the Jars to the same location as my three source files, but no change.
Can someone please tell me what I'm doing wrong?
Thanks.
Classpath variable (or command line option of javac) must contain all jars explicitly. It cannot go through jar files stored in specified directory.
You can compile this by specifying the option -cp on the command line:
javac -cp foo.jar:bar.jar foo/bar/Baz.java
You then run it with the same option:
java -cp foo.jar:bar.jar foo.bar.Baz
It sounds like you've just set the classpath to the directory containing the jar files. You need to set it to the individual jar files, or use java.ext.dirs to set an "extension" directory containing jar files. I'd recommend using the specific jar files. Something like:
// Assuming Windows...
CLASSPATH = c:\libs\foo.jar;c:\libs\bar.jar
I'd also personally recommend specifying the classpath on the command line instead of using an environment variable - the latter will work, but it ends up being a bit more fiddly if you want to compile different projects against different libraries.
However, I'd actually recommend getting Eclipse working first, rather than retreating to the command line. It should be fine - if you could give us more information about what's failing in Eclipse, we may be able to help you with that instead.
The jar files in the current directory are not automatically included; that only refers to .class files in normal package/directory hierarchy. Jar files must be added either explicitly, or via a wildcard like javac -cp ./* (Assuming JDK6+)
(Some OSes may require an escape of the * to avoid globbing; OSX does not.)
I agree with previous answers, but I would also recommend to use proper java build tool - like ant (perceived easier to use, but not necessary) or maven ( perceived more difficult to use, but really worth learning )

How to compile Java program with .jar library

I can't make javac recognize an external .jar file, whose classes I'm trying to extend. I have two files in the same directory: TestConsole.java and acm.jar. I'm compiling from the same directory using the following command:
javac -classpath .:acm.jar TestConsole.java
But it seems like javac is just ignoring acm.jar. It gives me the error:
TestConsole.java:1: package acm does not exist
import acm.program;
^
Of course, acm.program is a package in acm.jar. All of the classes in acm.jar are already compiled; I just want to use them in my classes, not compile them.
What am I doing wrong?
I am running this on a Mac, and the directory structure of acm.jar appears to be valid: It contains an acm/program directory, which has ConsoleProgram.class, the only class that TestConsole extends.
javac -classpath ".:acm.jar" TestConsole.java does not work, either.
javac -cp <jar you want to include>;<jar you want to include> <source.java>
<jar you want to include> if in same directory, just name of jar will do, if not, specify full or relative paths
if more than one jars, separate with ,
replace ; with : on unix
If possible, use some IDE like Eclipse. I used to spend a lot of time on similar things, but in industry, you will hardly ever do it in this fashion.
Are you running these commands on a Windows machine? On Windows, the elements of the classpath are separated by a semicolon, not a colon. So:
javac -classpath .;acm.jar TestConsole.java
Another possibility: the structure of acm.jar is wrong. It's not sufficient that the class files inside were compiled from files that declare package acm.program - the package structure must also be represented as a directory hierarchy, so acm.jar must contain a directory acm, and within that a subdirectory program that contains the actual class files for the classes used in TestConsole.
Check list:
your classes in acm.jar appear as:
acm/program/CLASSX.class
acm/program/CLASSY.class
when decanted with jar tf acm.jar
You're importing them like:
import acm.program.CLASSX ;
or
import acm.program.* ;
Whoever is trying to compile and still having the problem as I struggled for hours, I tried all the answers above and still was not able to run the program due to one minor issue.
The no-brainier issue was the semi colon after every package. I am not sure about Mac or Linux but for Windows Command Prompt this was the case
javac -cp mysql-connector-java-8.0.12.jar; Testing.java
java -cp mysql-connector-java-8.0.12.jar; Testing
You might wanna follow this both cases either in compilation or while running.
Many years behind but i struggled with this syntax, this worked for me to add all jar files plus compile with all classes in the program to the main class
My File Tree:
Store classes .java files
jars .jar files
images .PNG files
command line:
C:\Store>javac -cp "jars/" classes/.java classes/storeMain.java
I'm just adding for folks who are still looking for the answer to the same problem after successful compilation.
While compiling use the command as suggested above by #Michael Borgwardt:
javac -classpath .;acm.jar TestConsole.java
For executing also you need to specify the class path:
java -classpath .;acm.jar TestConsole

compiling multiple java classes in linux

i used netbeans to code the classes and they are all included in a package but when i try to compile the application class in linux it spits out errors on class definitions for the classes i am working with. points at the class names for the objects and says "cannot find symbol" i need help!!!
use javac -sourcepath < your source code path >
Better check -help option as it mostly solve your problems
cd to the directory containing your package then run:
javac -classpath . your_package_name/*
I'm not a Java guru, but I have a small java project that I developed years ago and have recently ported to compile with javac on Linux.
I got this to work in two different ways:
Created a single Java source file that held all of my classes
Put each of my classes in a separate file but all in the same directory
In each case, I can compile and run with the following:
javac *.java && java name_of_main_class
Notice that I did not specify a "-classpath" option when I compiled. I guess this works because I have not used a directory substructure or created a package. If you are dealing with those issues, this page appears to have some examples that may help you: Help with packages in java - import does not work
A key thing to understand about Java packages: They correspond to subdirectories where the classes are defined (or to JAR files which just bundle and compress those subdirectories into a single file). Therefore, anytime you specify the package keyword in your source, you need to make sure that the source files (and the class files) are distributed to subdirectories correspondingly. The -classpath option to javac may provide a workaround when subdirectory structures do not exactly match what is specified by the package keyword.
If you built the project using NetBeans, you can use Ant to build the project on command line. NetBeans generate Ant Build script.
just cd into the directory where the project is located then type 'ant'
it should build the project for you automagically

Categories