I cannot use a class in jar's root when my file is part of a package but when my file is not part of a package, I can.
Possibly another way to descibe the problem: A java file in the default package can refer to a class in the jar's unnamed package (class in the root of jar) but a java file in a named package cannot.
I've created a bash script to reproduce the problem.
build the jar
#!/bin/bash
# Create directory structure
mkdir -p projA/src/java/org/example
mkdir -p projA/out/artifacts
# Create Java source files
cat > projA/src/java/Class2.java << EOF
public class Class2 {
// Empty class
}
EOF
cat > projA/src/java/org/example/Class1.java << EOF
package org.example;
public class Class1 {
// Empty class
}
EOF
# Compile Java files
find projA/src/java -name "*.java" > sources.txt
javac -d projA/target @sources.txt
# Create JAR file
jar cf projA/out/artifacts/projA.jar -C projA/target .
# View contents of JAR file
tar tf projA/out/artifacts/projA.jar
use the jar
#!/bin/bash
# Create directory structure
mkdir -p ProjB/src/java/org/fred
# Create Java source files
cat > ProjB/src/java/Main2.java << EOF
public class Main2 {
public static void main(String[] args) {
Class2 class2 = new Class2();
}
}
EOF
cat > ProjB/src/java/org/fred/Main1.java << EOF
package org.fred;
import org.example.Class1;
public class Main1 {
public static void main(String[] args) {
Class1 class1 = new Class1();
// Class2 class2 = new Class2(); // <--- UNCOMMENT THIS TO REVEAL PROBLEM
}
}
EOF
# Compile Java files
javac -d ProjB/target -cp projA/out/artifacts/projA.jar ProjB/src/java/*.java ProjB/src/java/org/fred/*.java
# Run the classes
java -cp ProjB/target:projA/out/artifacts/projA.jar Main2
java -cp ProjB/target:projA/out/artifacts/projA.jar org.fred.Main1
After running these scripts in a fresh directory, everything should compile, build and run ok. Now uncomment the line with // <--- UNCOMMENT THIS TO REVEAL PROBLEM
and run the second script again. Notice the compiler error
ProjB/src/java/org/fred/Main1.java:12: error: cannot find symbol
Class2 class2 = new Class2();
Why can't I refer to Class2 - its clearly in the root of the jar. I can refer to it successfully from ProjB/src/java/Main2.java
but not from ProjB/src/java/org/fred/Main1.java
?
Interestingly, I don't need to use an import statement to when I'm referring to classes in the jar unnamed package (class in the root of jar) from a java file in the default package.