Class-Path entry for a jar manifest file

H

hiwa

To simplify the presentation of the problem, suppose we have the following
directory structure:

current directory ... TestApp.class file
SupportClass subir ... ReadRes.class file
Resources subdir ... Message.txt file

Here are the code:

--TestApp.java--
import java.io.*;

public class TestApp{
public static void main(String[] args) throws IOException{
ReadRes rs = new ReadRes();
System.out.println(rs.getStr());
}
}

--ReadRes.java--
import java.io.*;

public class ReadRes{
public String getStr() throws IOException{
InputStream is = TestApp.class.getResourceAsStream
("/Resources/Message.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
return(br.readLine());
}
}

--Message.txt--
Hello World!

This application runs with an ordinary command line as follows:
(use ; instead of : on Windows)

java -cp .:SupportClass TestApp

Now we have made a jar file with the following command:

jar mvf manifest TestApp.class SupportClass Resources

--manifest--
Manifest-Version: 1.0
Main-Class: TestApp
Class-Path: ?????

Then, the problem is: what should be the correct Class-Path entry in our
manifest file?

If you kindly test these jar-archived files, please beware that there
shoud be no original class/resource files around your testing directories.
And, note that there is no package issue nor multiple jar files issue
involved. Here we only see a plain old directory structure.

Thanks in advance.
 
J

John C. Bollinger

hiwa said:
To simplify the presentation of the problem, suppose we have the following
directory structure:

current directory ... TestApp.class file
SupportClass subir ... ReadRes.class file
Resources subdir ... Message.txt file

Here are the code:

--TestApp.java--
import java.io.*;

public class TestApp{
public static void main(String[] args) throws IOException{
ReadRes rs = new ReadRes();
System.out.println(rs.getStr());
}
}

--ReadRes.java--
import java.io.*;

public class ReadRes{
public String getStr() throws IOException{
InputStream is = TestApp.class.getResourceAsStream
("/Resources/Message.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
return(br.readLine());
}
}

Classes that belong to a default package instead of an explicit one
suffer from several limitations, so do yourself a favor and learn to use
packages. Then when you build a jar, lay out the classes inside it in a
directory structure corresponding to the package name structure (as it
is also appropriate to do on the filesystem). Do not seperate classes
by function, except insomuchas that seperation may already be reflected
in the assigned packages.

The class-path header in a manifest file is mainly intended for use when
you package other jars inside your jar; in that case you specify a list
of jar names relative to the root of the containing jar file. The
effect is that classes loaded from your jar will have those additional
jars in their class path.

You might want to look at the Jar trail of the Java Tutorial.


John Bollinger
(e-mail address removed)
 
H

hiwa

John C. Bollinger said:
hiwa said:
To simplify the presentation of the problem, suppose we have the following
directory structure:

current directory ... TestApp.class file
SupportClass subir ... ReadRes.class file
Resources subdir ... Message.txt file

Here are the code:

--TestApp.java--
import java.io.*;

public class TestApp{
public static void main(String[] args) throws IOException{
ReadRes rs = new ReadRes();
System.out.println(rs.getStr());
}
}

--ReadRes.java--
import java.io.*;

public class ReadRes{
public String getStr() throws IOException{
InputStream is = TestApp.class.getResourceAsStream
("/Resources/Message.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
return(br.readLine());
}
}

Classes that belong to a default package instead of an explicit one
suffer from several limitations, so do yourself a favor and learn to use
packages. Then when you build a jar, lay out the classes inside it in a
directory structure corresponding to the package name structure (as it
is also appropriate to do on the filesystem). Do not seperate classes
by function, except insomuchas that seperation may already be reflected
in the assigned packages.

The class-path header in a manifest file is mainly intended for use when
you package other jars inside your jar; in that case you specify a list
of jar names relative to the root of the containing jar file. The
effect is that classes loaded from your jar will have those additional
jars in their class path.

You might want to look at the Jar trail of the Java Tutorial.


John Bollinger
(e-mail address removed)

Thanks John for your typical Java adult reply. But here we
need a solution which doesn't use Java package framework nor
a set of different jar files. And I firmly believe there would
be none persuasive rationale for the absense of a viable
Class-Path entry syntax for a plain old directory structure
which is jar-archived.
 
J

John C. Bollinger

hiwa said:
John C. Bollinger said:
hiwa wrote:

To simplify the presentation of the problem, suppose we have the following
directory structure:

current directory ... TestApp.class file
SupportClass subir ... ReadRes.class file
Resources subdir ... Message.txt file

Here are the code:

--TestApp.java--
import java.io.*;

public class TestApp{
public static void main(String[] args) throws IOException{
ReadRes rs = new ReadRes();
System.out.println(rs.getStr());
}
}

--ReadRes.java--
import java.io.*;

public class ReadRes{
public String getStr() throws IOException{
InputStream is = TestApp.class.getResourceAsStream
("/Resources/Message.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
return(br.readLine());
}
}

Classes that belong to a default package instead of an explicit one
suffer from several limitations, so do yourself a favor and learn to use
packages. Then when you build a jar, lay out the classes inside it in a
directory structure corresponding to the package name structure (as it
is also appropriate to do on the filesystem). Do not seperate classes
by function, except insomuchas that seperation may already be reflected
in the assigned packages.

The class-path header in a manifest file is mainly intended for use when
you package other jars inside your jar; in that case you specify a list
of jar names relative to the root of the containing jar file. The
effect is that classes loaded from your jar will have those additional
jars in their class path.

You might want to look at the Jar trail of the Java Tutorial.


John Bollinger
(e-mail address removed)


Thanks John for your typical Java adult reply. But here we
need a solution which doesn't use Java package framework nor
a set of different jar files. And I firmly believe there would
be none persuasive rationale for the absense of a viable
Class-Path entry syntax for a plain old directory structure
which is jar-archived.

If you are not satisfied with the way that the URLClassLoader loads
classes from Jar files then you are free to write your own classloader
that works however you want. Neither I nor you can force URLClassLoader
to do what it does not do, however, at least not without violating the
Java license under which we use the Java SDK.

I am not in a position to explain Sun's design and implementation
choices, but I submit that I have never personally found the limitations
of URLClassLoader to be particularly chafing. I am, on the other hand,
a bit curious about why you are unable to use packages. Even if you
have hundreds of source files it shouldn't be too hard to write a script
to put appropriate package and import statements into all of them, and
to move them into a correctly structured directory hierarchy if necessary.

The other alternative is to forget about the internal jar layout you
described and just flatten it out. (I.e. instead of adopting a package
structure to match the jar layout you want, modify the jar layout to
match the package structure you insist on keeping.) I think that would
work, at least. I'm not certain what the value of any particular
internal jar's internal layout is if that layout is not required /
supported by the tools you are using.

If none of those suggestions are satisfactory then you probably need to
give the group a better idea of your requirements in order to get much help.


John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top