jar file contents when there is an imported package

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

Post Reply
abashdesh
Posts: 14
Joined: Sat Jul 17, 2021 8:22 am
Contact:

jar file contents when there is an imported package

Post by abashdesh »

Hi,

I tried the simple A package B package example given in the book - Oracle© Certified Professional Java SE 11 Programmer I Fundamentals (Exam Code 1Z0-815).

Package structure is like this -

---A
|---a.class
---B
|---b.class

a.class imports package B and class b.

Then I created a jar file with the following command -

jar -cvf a.jar A

Then I displayed the contents of the jar file using "jar -tf a.jar" command, and I see the following -

META-INF/
META-INF/MANIFEST.MF
A/
A/a.class

How come B/b.class is not a part of the jar file when A/a.class imports it?

Also how does A/a.class runs correctly with B/b.class being a part of it?

java -cp ./A.jar A.a
Hello 1 2 3 testing...

admin
Site Admin
Posts: 10046
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: jar file contents when there is an imported package

Post by admin »

1. When you create a jar file, only those files are added to the jar that you specify in the command (i.e. either as individual files or as a part directory).
The jar command does not inspect the content of the files that you are adding to the jar. It doesn't care what import statements you have.
Since you specified directory A in the jar command, it added only A and its contents to the jar.

2. Just because a.java imports class b, doesn't mean a uses b.
If your A.a class is running fine that means, it is not really using class B.b. Try doing using class b such as by adding this line in a's main:
B.b x = null; Then it will fail.
If you like our products and services, please help us by posting your review here.

abashdesh
Posts: 14
Joined: Sat Jul 17, 2021 8:22 am
Contact:

Re: jar file contents when there is an imported package

Post by abashdesh »

Thanks very much for the answer. I tried adding B package explicitly using "jar -cvf a.jar A B" and now the a.jar has both A.a class and B.b class.

I still didn't get a failure when a.jar did not have B.b class added. Even before, I had created a reference object of b class and after your reply I also tried adding B.b x = null;

Here is the code i used on a.java class -

package A;

import B.b;

public class a {
b bobj = new b();
b x = null;
public static void main(String[] args){
System.out.println("Hello 1 2 3 testing...");
}
}

The above code prints "Hello 1 2 3 testing..." when run using following and when B.b is not added to the a.jar file -
java -cp ./a.jar A.a
Hello 1 2 3 testing...

Thanks,
abashdesh

admin
Site Admin
Posts: 10046
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: jar file contents when there is an imported package

Post by admin »

By default, java looks for class files in the current directory as well. Since you have B/b.class in your current directory, it worked. Delete b.class altogther from your folders and then run it. It will fail to run.
If you like our products and services, please help us by posting your review here.

abashdesh
Posts: 14
Joined: Sat Jul 17, 2021 8:22 am
Contact:

Re: jar file contents when there is an imported package

Post by abashdesh »

Tried multiple times -
1. Removed B directory from the current directory, but the a.jar still ran with "Hello 123 testing..." output.
2. Removed A directory and recompiled a.java (with no B directory present) and then removed re-created a.jar with only A, still it ran.
3. Only when I added the following code that does a Sysout from class b and its called from class a, then it gave me the error.
Error was received even when B was present in the current directory.

Code added, recompiled a.java and b.java and recreated a.jar -
package B;

public class b{
public static void hello(){
System.out.println("Hello from class b");
}
}

package A;

import B.b;

public class a {
b bobj = new b();
b x = null;
public static void main(String[] args){
System.out.println("Hello 1 2 3 testing...");
b.hello();
}
}

java -cp ./a.jar A.a
Hello 1 2 3 testing...
Exception in thread "main" java.lang.NoClassDefFoundError: B/b
at A.a.main(a.java:10)
Caused by: java.lang.ClassNotFoundException: B.b
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

4. Then I re-created a.jar by adding B to it and then it worked without run-time error.

Probably JVM was looking for an actual executable statement, with just adding a reference assignment statement, somehow it was till working.

admin
Site Admin
Posts: 10046
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: jar file contents when there is an imported package

Post by admin »

Right, if you have both a.class and b.class in the jar, then just putting the jar in the classpath is enough. There is no need to have b.class separately.

If you have only a.class in the jar, but B/b.class is in the current directory, then also it will work because the jvm will find B/b.class in current directory. In your original post, your code was working for this reason.
If you like our products and services, please help us by posting your review here.

abashdesh
Posts: 14
Joined: Sat Jul 17, 2021 8:22 am
Contact:

Re: jar file contents when there is an imported package

Post by abashdesh »

Hi,

If you see points 1 and 2 above what you are saying was not the case. Failure happened only when I added a Sysout call on b class and then called it from a class. When I had only created reference of b class (and nothing else) then it was working even when -
1. B.b was removed from the current directory and also not present in the jar

Hence I was asking if creating only a reference works, but again its puzzling from where it is taking the B.b class.

abashdesh
Posts: 14
Joined: Sat Jul 17, 2021 8:22 am
Contact:

Re: jar file contents when there is an imported package

Post by abashdesh »

Apols, tried this again by removing B directory from current directory and it started giving me compilation error. So what you are saying is correct it was looking at current directory by default.

Post Reply

Who is online

Users browsing this forum: No registered users and 70 guests