Java Forum / First Aid / November 2003
Dont work in a jar
Qu?bec - 21 Nov 2003 21:59 GMT Hi,
I have modify a bit this code from "Cay Horstmann" but it does not find the .caesar class and the catalog.txt from inside a jar file. I I jar everything and add the two files 'outside' the jar it works fine.
I tried to fit getRessourceAsStream in it without success. Any clue appreciated,
Jean
======================
import java.util.*; import java.io.*; import java.lang.reflect.*; import java.awt.*; import java.awt.event.*; import javax.swing.*;
class MyClassLoader extends JFrame { public static void main(String[] args) { new MyClassLoader().runClass(); } public void runClass() { try { ClassLoader loader = new CryptoClassLoader(); Class c = loader.loadClass("MusicCatalog"); String[] args = new String[] {};
Method m = c.getMethod("main", new Class[] { args.getClass() }); m.invoke(null, new Object[] { args }); } catch (Throwable e) { JOptionPane.showMessageDialog(this, e); } } }
class CryptoClassLoader extends ClassLoader { protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // check if class already loaded Class cl = (Class)classes.get(name);
if (cl == null) // new class { try { // check if system class return findSystemClass(name); } catch (ClassNotFoundException e) {} catch (NoClassDefFoundError e) {}
// load class bytes--details depend on class loader
byte[] classBytes = loadClassBytes(name); if (classBytes == null) throw new ClassNotFoundException(name);
cl = defineClass(name, classBytes, 0, classBytes.length); if (cl == null) throw new ClassNotFoundException(name);
classes.put(name, cl); // remember class }
if (resolve) resolveClass(cl);
return cl; }
private byte[] loadClassBytes(String name) { String cname = name.replace('.', '/') + ".caesar"; FileInputStream in = null; try { in = new FileInputStream(cname); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) != -1) { byte b = (byte)(ch - 3); buffer.write(b); } in.close(); return buffer.toByteArray(); } catch (IOException e) { if (in != null) { try { in.close(); } catch (IOException e2) { } } return null; } }
private Map classes = new HashMap(); }
Chris Smith - 21 Nov 2003 23:09 GMT Québec wrote:
> Hi, > [quoted text clipped - 3 lines] > > I tried to fit getRessourceAsStream in it without success. The code you posted looks for files relative to the current working directory, *not* for resources in a JAR file. Your expectations of what it does are incorrect. The right way to accomplish your goal is to use getResourceAsStream to load the resources.
If you have tried this and it didn't work, you need to post the code you tried, so that someone can figure out what didn't work about it.
 Signature www.designacourse.com The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
biswa - 22 Nov 2003 06:23 GMT class files / files in jar files are not added automatically, you have to add the path of your jar file to the class path. If you are using jar file in tomcat application (web application) , you may keep the jar file under lib folder of web-inf to load jar files automatically and you do not have to manually add the jar file path.
hope it helps. biswa.
Qu?bec - 22 Nov 2003 21:02 GMT >If you have tried this and it didn't work, you need to post the code you tried, so that someone can figure out what didn't work about it.
String catalogFile = "catalog.txt"; ArrayList albumList;
try { InputStream is = MusicCatalog.class.getResourceAsStream(catalogFile); albumList = ReadFile(new BufferedReader(is));
Qu?bec - 22 Nov 2003 22:29 GMT It sems I get it.....
File data = new File(dataFile); InputStream is = MusicCatalog.class.getResourceAsStream(dataFile); br = new BufferedReader(new InputStreamReader(is));
it works .... now I will se for the class....
Qu?bec - 22 Nov 2003 23:04 GMT Although the same method works to load a txt file from a jar. Loading the class does not work. If I put the class.caesar outside the jar the MyLoader works.
See in between ==============
====================
class MyClassLoader { public static void main(String[] args) { new MyClassLoader().runClass(); } public void runClass() { try { ClassLoader loader = new CryptoClassLoader(); Class c = loader.loadClass("MusicCatalog"); String[] args = new String[] {}; Method m = c.getMethod("main", new Class[] { args.getClass() }); m.invoke(null, new Object[] { args }); } catch (Throwable e) { JOptionPane.showMessageDialog(null, e); } } }
class CryptoClassLoader extends ClassLoader { protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // check if class already loaded Class cl = (Class)classes.get(name);
if (cl == null) // new class { try { // check if system class return findSystemClass(name); } catch (ClassNotFoundException e) {} catch (NoClassDefFoundError e) {}
// load class bytes--details depend on class loader
byte[] classBytes = loadClassBytes(name); if (classBytes == null) throw new ClassNotFoundException(name);
cl = defineClass(name, classBytes, 0, classBytes.length); if (cl == null) throw new ClassNotFoundException(name);
classes.put(name, cl); // remember class }
if (resolve) resolveClass(cl);
return cl; }
private byte[] loadClassBytes(String name) { String cname = name.replace('.', '/') + ".caesar"; InputStreamReader in = null; try { ================================ InputStream is = MusicCatalog.class.getResourceAsStream(cname); in = new InputStreamReader(is); ============================== ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) != -1) { byte b = (byte)(ch - 3); buffer.write(b); } in.close(); return buffer.toByteArray(); } catch (IOException e) { if (in != null) { try { in.close(); } catch (IOException e2) { } } return null; } }
private Map classes = new HashMap(); }
Chris Smith - 24 Nov 2003 14:26 GMT Québec wrote:
> Although the same method works to load a txt file from a jar. Loading the > class does not work. If I put the class.caesar outside the jar the MyLoader > works. Okay...
> private byte[] loadClassBytes(String name) > { String cname = name.replace('.', '/') + ".caesar"; [quoted text clipped - 4 lines] > in = new InputStreamReader(is); > ============================So what package is CryptoClassLoader in? The ".caesar" file needs to be in a subdirectory of the dir for that package, according to it's own package. Hence, if CryptoClassLoader is in com.mypackage, and the class you want to load is com.mypackage.MyClass, then the resource needs to be:
/com/mypackage/com/mypackage/MyClass.caesar
That's the way you've written your code.
(Incidentally, did you intend for your "encrypted" classes to not work reliably on other platforms from the one you are developing on? If not, then you need to specify a definite encoding, rather than relying on the platform default. You'll need to pick an encoding where all of the lower 256 unicode characters are valid.)
 Signature www.designacourse.com The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Qu?bec - 24 Nov 2003 15:23 GMT All classes are default package.
Chris Smith - 24 Nov 2003 18:48 GMT Québec wrote:
> All classes are default package. Then I don't know. There's no reason you should be able to load a '.txt' file as a resource, but not a '.caesar' file. The only thing that comes to mind is that Netscape, in a version long ago and far away, used to have a bug that restricted getResource to loading files with known extensions... you aren't using an old version of Netscape, are you?
(BTW, thanks for pointing out the problem with port 80 of our Design-a- Course server. I've passed it along to our sysadmin people.)
 Signature www.designacourse.com The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Qu?bec - 24 Nov 2003 19:31 GMT I am using ie 6.
I think Sun never came up with a nice solution for is jars. I am trying to do an application, so the browers are not part of the problem.
Qu?bec - 24 Nov 2003 15:28 GMT I am just trying to learn from this. ===> (ch + key);
=================== /** * @version 1.00 1997-09-10 * @author Cay Horstmann */
import java.io.*;
public class Caesar { public static void main(String[] args) { if (args.length != 3) { System.out.println("USAGE: java Caesar <named class in> <to name class out> key"); return; }
try { FileInputStream in = new FileInputStream(args[0]); FileOutputStream out = new FileOutputStream(args[1]); int key = Integer.parseInt(args[2]); int ch; while ((ch = in.read()) != -1) { byte c = (byte)(ch + key); out.write(c); } in.close(); out.close(); } catch(IOException e) { System.out.println("Error: " + e); } } } ================
>www.designacourse.com This link seems to be broken...
Qu?bec - 26 Nov 2003 00:19 GMT Hi,
Ok. Now it works. Everything is loaded but I have to (hack) put System exit(0) for the ClassLoader not to hang after the main class (main method) ends.
================== class MyClassLoader {
public static void main(String[] args) { new MyClassLoader().runClass(); System.exit(0); =====================???? }
public void runClass() { try { ClassLoader loader = new CryptoClassLoader(); Class c = loader.loadClass("MusicCatalog"); String[] args = new String[] {};
Method m = c.getMethod("main", new Class[] { args.getClass() }); m.invoke(null, new Object[] { args }); } catch (Throwable e) { JOptionPane.showMessageDialog(null, e); } =========== tried a 'return;' here without success } }
class CryptoClassLoader extends ClassLoader { protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // check if class already loaded Class cl = (Class)classes.get(name);
if (cl == null) // new class { try { // check if system class return findSystemClass(name); } catch (ClassNotFoundException e) {} catch (NoClassDefFoundError e) {}
// load class bytes--details depend on class loader
byte[] classBytes = loadClassBytes(name); if (classBytes == null) throw new ClassNotFoundException(name);
cl = defineClass(name, classBytes, 0, classBytes.length); if (cl == null) throw new ClassNotFoundException(name);
classes.put(name, cl); // remember class }
if (resolve) resolveClass(cl);
return cl; }
private byte[] loadClassBytes(String name) { String cname = name.replace('.', '/') + ".caesar"; FileInputStream in = null; try { in = new FileInputStream(cname); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) != -1) { byte b = (byte)(ch - 3); buffer.write(b); } in.close(); return buffer.toByteArray(); } catch (IOException e) { if (in != null) { try { in.close(); } catch (IOException e2) { } } return null; } }
private Map classes = new HashMap(); }
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|