I try to compile this code:
package edu;
import java.io.*;
public class Main { ... }
with javac called from command line. I know that I need to do it this way:
javac -classpath /lib/* Main.java
and put .jar file with the 'java.io.*' classes in 'lib' folder in my project's directory.
Is my javac command correct - especially path to '/lib/*'?
How do I find the desired .jar file(s) so that I can copy them to my project's lib directory?
package java.io is part of core java, you do not have to put anything extra into your classpath
Related
How can I import file from outside of package?
example:
// this is a.java
package user.code.gui;
void method_a(){
// do something
}
and
// this is b.java
package user.code;
void method_b(){
// do something
}
and
// this is c.java
package user.extensions;
void method_c(){
// do something
}
If I use "import c" in file a.java, it can't find this file because it's in a different package. The problem is, how can I import file c.java in file a.java?
You need the other package to be there during compilation, and also during runtime; these are different things, but they both have the concept of a classpath.
Java always looks for things by translating type names to dir names; package a.b; class Foo {} is looked for in /a/b/Foo.class.
It scans each entry in the classpath for that. Classpath entries can be either directories, or jar files.
Build systems (maven, gradle, etc) and IDEs (eclipse, intellij, etc) - make this easily configurable and in general take care of it for you. You should use these tools; 99% of all java projects are compiled by IDEs and/or build tools.
Once you start having multiple packages, javac becomes unwieldy.
But, if you must use the command line for it:
Your directory structure:
/Users/Cflowe/workspace/MyAwesomeProject/src/user/code/gui/GuiClass.java
/Users/Cflowe/workspace/MyAwesomeProject/src/user/code/Whatever.java
and so on. To compile:
cd /Users/Cflowe/workspace/MyAwesomeProject
mkdir bin
javac -sourcepath src -d bin src/user/code/Whatever.java src/user/code/gui/GuiClass.java andSpecifyEveryOtherFileByHandHere
java -cp bin com.foo.Main
I'm trying to compile my Java program into an executable jar file, and I've tried following all the instructions in various places, but I'm encountering an issue.
Class Files
The first thing I do is compile everything to class files with this command.
javac -d ./build src/main/**/*.java -cp lib/main/commons-cli-1.4/commons-cli-1.4.jar:lib/main/commons-io-2.8.0/commons-io-2.8.0.jar
This compiles all the .java files in src/main (I don't want to compile the tests of course) into a folder called build. It also sets the classpath to all the .jar files that the code depends on (Apache Commons CLI and Apache Commons IO).
Jar Files
The next step is to generate the .jar file. For this, I use the following command (after cd ./build).
jar cvfm ../bin/program.jar manifest.txt .
Here, manifest.txt is in the folder build and contains the following. (It ends with a trailing newline, as per the documentation dictates.)
Main-Class: cli.Cli
Here, cli.Cli refers to the class named Cli located in src/main/cli/Cli.java which contains the main method.
Running the Jar
Now I use the following command to try to run the produced program.jar file, but I get this error.
$ java -jar build/program.jar
Error: Unable to initialize main class cli.Cli
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException
This error is referring to one of the import statements in src/main/cli/Cli.java, which is supposed to be in the same .jar file as all the other import statements. The IDE does recognise the import, but I'm not sure why I am unable to run the file. Here is an extract of my imports from Cli.java.
package cli;
import java.io.IOException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.io.FilenameUtils;
// more imports...
Edit
I tried to change the manifest to contain a classpath, but that didn't seem to help at all. I tried the following two versions of the manifest.
Relative to bin/ or build/:
Main-Class: cli.Cli
Class-Path: ../lib/main/commons-cli-1.4/commons-cli-1.4.jar:../lib/main/commons-io-2.8.0/commons-io-2.8.0.jar
Relative to workspace folder (which is the current directory when I run the jar):
Main-Class: cli.Cli
Class-Path: lib/main/commons-cli-1.4/commons-cli-1.4.jar:lib/main/commons-io-2.8.0/commons-io-2.8.0.jar
Edit 2
I changed my code to not use ParseException but then another of the imports caused the same error.
Turns out the classpath in the manifest needed to be space-separated, with the paths to each jar relative to bin/, like so:
Main-Class: cli.Cli
Class-Path: ../lib/main/commons-cli-1.4/commons-cli-1.4.jar ../lib/main/commons-io-2.8.0/io-2.8.0.jar program.jar
My project contains three source files that I have created and one testing file (Homework1.java). The directory structure looks like this:
ija/ija2016/homework1/HomeWork1.java
ija/ija2016/homework1/cardpack/Card.java
ija/ija2016/homework1/cardpack/CardDeck.java
ija/ija2016/homework1/cardpack/CardStack.java
The HomeWork1.java file contains the main method, some tests and also imports the other three files:
import ija.ija2016.homework1.cardpack.Card;
import ija.ija2016.homework1.cardpack.CardDeck;
import ija.ija2016.homework1.cardpack.CardStack;
Now I am able to compile the Card.java, CardStack.java and CardStack.java, but I am only able to do so directly from the /cardpack/ directory. When I try to compile them from anywhere else, then the CardDeck and CardStack classes don't recognize the Card symbol.
My question is, how do I compile the project as a whole? Should the three source files that I have created have import package in the header (the CardStack and CardDeck use the Card class)?
in your root folder, try to run:
$javac -cp . ija/ija2016/homework1/HomeWork1.java
then you can run your program
$java -cp . ija/ija2016/homework1/HomeWork1
-cp/-classpath: defines your classpath.
I'm trying to figure out how an existing Java program (I did not make myself ofcourse) was compiled with existing jars
I have Test.java (original source file):
package Demo;
//import classes from jars here etc...
public class Test {
public static void main(String args[]) {
etc...
}
}
Now I have two other jars:
file1.jar
file2.jar
Demo.jar
There is a batch script to run it:
#echo off
set CLASSPATH="file1.jar";"file2.jar";"Demo.jar"
java -cp %CLASSPATH% Demo.Test
This WORKS, but now I need to change the source file Test.java, recompile and run with the jars class dependencies. (sorry if I'm not making sense)
Now, I have tried to recompile this to reproduce same results with no luck:
javac -cp file1.jar;file2.jar;Demo.jar Test.java
defined manifest:
manifest.mf
Main-class: Demo.Test
Created directory "store" for class files and moved class files there
Ran:
jar -cmf manifest.mf Demo.jar store
Which created the "Demo.jar"
Then I ran the run the batch script above but not the same results (doesn't work at all)
Any help would be appreciated. Thank you!
It is difficult to create true executable jars as soon as you rely on external jars.
The only solution here is to :
put all jars in the same folder : yours and its dependencies
add a classpath entry inside your manifest
launch the jar using java -jar Demo.jar
The manifest will have to look like :
manifest.mf
Main-class: Demo.Test
Class-Path: file1.jar file2.jar
I have a source file SerialTalk.java, in directory C:\javasrc\BattProj
This file imports classes from RXTXcomm.jar, eg.
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
...
RXTXcomm.jar is in the same directory as SerialTalk.java. I compile specifying a classpath pointing to the current directory:
javac -verbose -classpath . SerialTalk.java
Invariably, I get the following error. (Actually, many instances & variants of this error):
SerialTalk.java:3: error: package gnu.io does not exist
import gnu.io.CommPortIdentifier;
When I open the RXTXcomm.jar (eg. with 7-Zip) I can see the gnu.io structure, and the specific .class files that I'm trying to import.
So what am I doing wrong? The same .java (source) file has been compiled and run on another workstation within the Netbeans IDE. The difference here is I'm trying to compile it using javac from the command line. (Environment is Win7, 32 bit, jdk1.7.0_03)
So what am I doing wrong?
You're not putting the jar file on the class path. Putting the directory on the class path doesn't do it. That only tells javac where to find .class files in the directory structure, not jar files containing class files. You want:
javac -verbose -classpath .;RXTXcomm.jar SerialTalk.java