Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / November 2003

Tip: Looking for answers? Try searching our database.

Dont work in a jar

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.