How to compile and run java files from sub-directory - java

I'm trying to compile .java files and store them in a sub-directory called bin. I then want to run the generated .class files from the main directory. How can I do this?
Here's my Makefile:
# java compiler
JCC = javac
# output directory
OUTDIR = bin/
# compilation flags
JFLAGS = -g -d $(OUTDIR)
# default target entry
default: A.class B.class C.class
A.class: A.java
$(JCC) $(JFLAGS) A.java
B.class: B.java
$(JCC) $(JFLAGS) B.java
C.class: C.java
$(JCC) $(JFLAGS) C.java
# To start over from scratch, type 'make clean'.
# Removes all .class files, so that the next make rebuilds them
clean:
$(RM) $(OUTDIR)*.class
What I want to do:
make
java bin/A

You must specify the bin directory as the classpath of the JVM, using the -cp option
java -cp bin A
A being the fully qualified name of the class to run.

Related

javac -cp can not find class?

How to use the javac command, want to compile hello.java to hello.class, the file content is as follows:
How to introduce other packages, the directory structure is as follows
It's a mistake for me to run like this:
e:\icenew2\hellotest>javac -sourcepath src hello.java
It's wrong to run like this : javac -cp "src\com\zeroc\Ice*.class" hello.java
We can use the wildcard character *:
javac -cp *; BackBenchers.java
Specifying destination directory:
javac -d classes backbenchers.java
Note: The compiler will complain if the specified directory does not exist, and it won’t create one.
If the source file is under a package, the compiler will create package structure in the destination directory.
Specifying source path directory:
javac -sourcepath src BackBenchers.java

How to handle jars in a makefile for a java project

I need help incorporating jars(specifically mysql-connector-java.jar & javax.persistence_2.1.0.v201304241213.jar) into my makefile. I am aware that Make is not ideal for a java project, but due to requirements, using ant/Maven is not an option. So far my makefile looks like:
# Makefile brutally copypasta'd from previous CSC pracs.
LIB = ../lib
SRCDIR = src
BINDIR = bin
TESTDIR = test
DOCDIR = doc
JAVAC = javac
JFLAGS = -g -d $(BINDIR) -cp $(BINDIR)
vpath %.java $(SRCDIR)
vpath %.class $(BINDIR)
# define general build rule for java sources
.SUFFIXES: .java .class
.java.class:
$(JAVAC) $(JFLAGS) $<
all: client server
client: shared/NetMessage.class client/Command.class client/UploadConnectionThread.class client/DownloadConnectionThread.class client/MainConnectionThread.class client/ClientState.class client/Main.class
server: shared/NetMessage.class server/ConnectionInstance.class server/ServerState.class server/Main.class
# handling the cyclic dependency between ClientState and the connection thread classes:
client/ClientState.class: client/UploadConnectionThread.class client/DownloadConnectionThread.class client/MainConnectionThread.class
client/UploadConnectionThread.class client/DownloadConnectionThread.class client/MainConnectionThread.class: client/ClientState.java client/UploadConnectionThread.java client/DownloadConnectionThread.java client/MainConnectionThread.java
rm -f $(BINDIR)/client/ClientState.class $(BINDIR)/client/DownloadConnectionThread.class $(BINDIR)/client/UploadConnectionThread.class $(BINDIR)/client/MainConnectionThread.class
$(JAVAC) $(JFLAGS) $(SRCDIR)/client/ClientState.java $(SRCDIR)/client/UploadConnectionThread.java $(SRCDIR)/client/DownloadConnectionThread.java $(SRCDIR)/client/MainConnectionThread.java
# handling cyclic dependency between ServerState and ConnectionInstance
server/ServerState.class: server/ConnectionInstance.class
server/ConnectionInstance.class: server/ConnectionInstance.java server/ServerState.java
rm -f $(BINDIR)/server/ServerState.class $(BINDIR)/server/ConnectionInstance.class
$(JAVAC) $(JFLAGS) $(SRCDIR)/server/ServerState.java $(SRCDIR)/server/ConnectionInstance.java
# All the actual program classes
# compile/run commands
run_server: server
java -cp bin server.Main
run_client: client
java -cp bin client.Main 127.0.0.1
clean:
#rm -f $(BINDIR)/*.class
#rm -f $(BINDIR)/*/*.class
I have researched the Javadocs and other questions on SO, but the answers provided, are for simple project structures where the makefile produces classfiles in the same directory as the java files and no packages are used. In this case however the class files are created in bin/server (if they are server files) or the approriate bin/subdirectory. My project structure is as follows:
/bin
/server/
/client/
/shared/
/src
/server/
/client/
/shared/
/lib
/mysql-connector-java.jar
/javax.persistence_2.1.0.v201304241213.jar
/makefile
I have already tried adding the jars to the classpath as follows: CLASSPATH = /lib/mysql-connector-java.jar, but it does not work when I add the class path to the rule: .SUFFIXES: .java .class, as Make picks it up as multiple targets.

make file Java "missing operator" "none to do with default"

I am trying to build a make file for my program and Im getting the error missing operator at line 4 (javac $(JFLAGS)). I am also getting the error "none to do with default". Can someone help me with this error please? i have been stuck for quite a bit. Thank you much
JFLAGS = -g -d
JC = javac
%.class : %.java
javac $(JFLAGS)
CLASSES = \
Hello.java
default: $(CLASSES:.java=.class)
clean:
$(RM) *.class
You mention you are getting the error
make: Nothing to be done for 'default'.
This is not an error. It is make telling you that the target default is up to date and none of its prerequisites are older than it or need to be remade. For your particular case this will occur when the file Hello.class already exists in the same directory as your makefile. It is not an error but a simple message from make.
With regards to your other error
Java: missing operator at line 4
might this possibly say
makefile:4: *** missing separator. Stop.
instead? If that is the case then it means that you have not correctly indented the line
javac $(JFLAGS)
with a tab character.
Note: I mention this because it appears to be the closest error message to what you have described that I can replicate.
Another more pressing issue than the above is in particular your use of javac $(JFLAGS) and JFLAGS. In JFLAGS you have specified the -d option. When you execute javac $(JFLAGS) the error you get should look similar to
$ javac -g -d
javac: -d requires an argument
This is because the -d option when passed to javac is used to tell javac where the output directory that it should place .class files is. If you want your .class files to be output in the same directory as your makefile relative to their package name (see below) then you need to delete the -d option and declare JFLAGS as
JFLAGS = -g
If however, you dont want your .class files to be output in the same directory as your makefile then you need to declare a directory after the -d option in JFLAGS as
JFLAGS = -g -d /path/to/my/output/directory
Now that we've covered the -d option let's move on to actually compiling your .java files. The current rule you have is
%.class : %.java
javac $(JFLAGS)
this should to be altered to
%.class : %.java
$(JC) $(JFLAGS) $<
The automatic variable $< stands for the first prerequisite and will create a command like
$ javac -g Hello.java
for your particular example, which will create a Hello.class file in the same directory as the makefile and your Hello.java file.

make file for Java/Linux

I have the following makefile after running it once I make some changes to the makefile and now when I run it I get a "make: Nothing to be done for `default'." How can I force it to rebuild? I execute "make" and also "make clean" and I still get the error message when I type "make".
Also, how do I get the log4.properties file which is in the src directory to be copied over to the target directory (in the make file and on the command line: javac -classpath src:lib/log4j-1.2.16.jar src/*.java -d bin)?
#
# define compiler and compiler flag variables
#
JFLAGS = -g -cp .:src:lib/log4j-1.2.16.jar
JC = javac
#
# Clear any default targets for building .class files from .java files; we
# will provide our own target entry to do this in this makefile.
# make has a set of default targets for different suffixes (like .c.o)
# Currently, clearing the default for .java.class is not necessary since
# make does not have a definition for this target, but later versions of
# make may, so it doesn't hurt to make sure that we clear any default
# definitions for these
#
.SUFFIXES: .java .class
#
# Here is our target entry for creating .class files from .java files
# This is a target entry that uses the suffix rule syntax:
# DSTS:
# rule
# 'TS' is the suffix of the target file, 'DS' is the suffix of the dependency
# file, and 'rule' is the rule for building a target
# '$*' is a built-in macro that gets the basename of the current target
# Remember that there must be a before the command line ('rule')
#
.java.class:
$(JC) $(JFLAGS) $*.java
#
# CLASSES is a macro consisting of 4 words (one for each java source file)
#
CLASSES = \
src/MatrixDriver.java \
src/ConcreteMatrix.java \
src/Matrix.java \
src/Submatrix.java
#
# the default make target entry
#
default: classes
#
# This target entry uses Suffix Replacement within a macro:
# $(name:string1=string2)
# In the words in the macro named 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .java of all words in the macro CLASSES
# with the .class suffix
#
classes: $(CLASSES:.java=.class)
#
# RM is a predefined macro in make (RM = rm -f)
#
clean: FORCE
$(RM) *.class
FORCE:
The problem is that this:
.java.class:
$(JC) $(JFLAGS) $*.java
doesn't do what you think it does. Perhaps you meant something like this?
%.class: %.java
$(JC) $(JFLAGS) $^
I did not read your Makefile carefully and I do not consider myself a make expert
but
there does not seem to be any dependency on the Makefile itself
all you changed is the Makefile
leads me to think that the correct behavior is exactly what you described. Perhaps you can add a dependency to the Makefile.
Make sure there is no file or directory called classes. Make could then assume nothing more to do.

java class not found despite providing a jar file

I'm puzzled by the process of running java programs, maybe you can help.
I have several .java files in ~/working_dir/org/project/ that have main functions, and I want to package them in a jar to run them. I do:
cd ~/working_dir/org/projectname
javac -classpath $CLASSPATH *.java
cd ~/working_dir/
jar cf myjar.jar org/
And then try to run one of the classes in the jar by doing:
java -cp myjar.jar org.project.SomeClass
and get
Exception in thread "main" java.lang.NoClassDefFoundError: org/project/SomeClass
Could not find the main class: org.project.SomeClass
What do I do wrong? The classes compile without any errors, and jar tf myjar.jar shows that they're indeed there. As far as I know I don't need to create a Manifest file because I provide the class from which I want to run the main function at runtime - or am I wrong here?
Help much appreciated!
If the exploded jar org/project/SomeClass is beneath your current working dir:
/ <- you are here
+---/org
|
+-----/project
|
+--------SomeClass.class
try java -cp . org.project.SomeClass instead
First of all, note that if you simply do
javac org/project/SomeClass.java
the class file will end up right beside the .java file which makes it tricky to include only .class-files in the jar. I suggest you use the -d option to specify destination directory:
javac -d bin org/project/SomeClass.java
Have a look at the following bash-session for details to get it working:
A listing of the source directory:
user#host:/working_dir/src$ ls -R
.:
org
./org:
projectname
./org/projectname:
SomeClass.java
The SomeClass.java file:
user#host:/working_dir/src$ cat org/projectname/SomeClass.java
package org.project;
public class SomeClass {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Compile it (with target directory ../bin)
user#host:/working_dir/src$ javac org/projectname/SomeClass.java -d ../bin
List the result and make sure you got the directories right:
user#host:/working_dir/src$ cd ../bin/
user#host:/working_dir/bin$ ls -R
.:
org
./org:
project
./org/project:
SomeClass.class
Create the jar file:
user#host:/working_dir/bin$ jar cf myjar.jar org
Make sure you got the directories right and didn't accidentally include the "bin" directory:
user#host:/working_dir/bin$ jar tf myjar.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/project/
org/project/SomeClass.class
Launch the main method:
user#host:/working_dir/bin$ java -cp myjar.jar org.project.SomeClass
Hello World
user#host:/working_dir/bin$

Categories

Resources