8 Replies Latest reply: Dec 22, 2002 4:13 AM by 843802 RSS

    NoClassDefFound when running programmatically created JAR

    843802
      Hi guys. I know there have been loads of posts on this kind of subject, and I've trawled through the best part of them with no luck. I haven't found an answer and have been working on it eight hours straight now.


      The problem:

      I programatically create JAR files. This is no problem. I can then read/extract etc with these files using winzip and jar.exe no problem, so I'm sure I'm writing it correctly.

      However, when I specify a Main-Class in the manifest, it complains of a NoClassDefFoundError. I have checked, and the class is in the archive with the correct path.

      The main class is jaf.JAF , which is to say, a class called JAF.class in a package 'jaf'.

      No external jars are used. All the required files are either in the JAR, with a correct package/directory structure, or in rt.jar.

      Using the java -verbose option I can see it loads the rt.jar classes no problem, but fails immediately on accessing my jaf package. Curiously, if I run without the jar, e.g. java jaf.JAF, the program runs fine.

      The manifest file has two blank lines at the end.

      If anyone has any ideas I will be very grateful.

      Thanks in advance.
        • 1. Re: NoClassDefFound when running programmatically created JAR
          843802
          Maybe you can try this:

          java -classpath yourjar.jar YourMainClass

          I faced the same problem with command line created jar file.

          It looks like you have to explicitly mention the jar file in the classpath to work.

          If you find a solution to running a jar without specifying the classpath, please post your answer here. I tried modifying the system variable CLASSPATH too. But it did not work. I tried this on windows NT.

          • 2. Re: NoClassDefFound when running programmatically created JAR
            843802
            Thanks for replying! Unfortunately the classpath option is not appropriate here as there are no external libraries.

            However, I did establish the problem. For anyone who cares, here is the solution:

            When programmatically creating a JAR file, adding a manifest via the writeEntry(byte[]) method of JarOutputStream does work properly, even if the byte array is correct (e.g. read directly from a working manifest file).

            Using a Manifest object is the way to do it (which seems obvious now, but the API javadoc on the java.util.jar package is so crap and lacking in explanation or decent 'how-to' notes that it was not obvious how you add entries to a Manifest object). However, there are still problems. There are two ways to create a manifest object:

            1- Specify the inputstream from which to read the manifest. This is useful if you already have an existing, working, manifest file. BUT THIS DOESN'T ALWAYS WORK!. Under these conditions, I get an 'Invalid Header Entry Name' error when it reaches my 'Main-Class' header.

            2- (THIS IS THE ONE TO USE) Add individual entries to the Manifest object in the following manner:

            Manifest m=new Manifest();
            m.getMainAttributes().putValue("Manifest-Version", "1.0");
            m.getMainAttributes().putValue("Main-Class", "MyClass");

            Then write the JarFile with a JarOutputStream (using the constructor which accepts an OutputStream and a Manifest).

            I have spent three weeks wrestling with the java.util.jar package. There are no tutorials on the subject (unless you count Sun's JarRunner tutorial which does not cover anything to do with creating JAR files programmatically). Frankly, I am disappointed there are not more examples on the subject. Grrrrrrrr...

            fgatschool, thanks for trying :-) I can't retract my dukes so you may as well have them. I appreciate the effort you took to reply.
            • 3. Re: NoClassDefFound when running programmatically created JAR
              843802
              Hi Silly,
              This forum is good! I am learning by these exchanges. Also I would like to share my experience in trying to create an executable jar which I finally succeeded today. I suppose, even though this is not programmatically created, it may shed some light on your problem.

              My Manifest info were as follows:

              Manifest-Version: 1.0
              Main-Class: MyMainClass
              Class-Path: xercesImpl.jar xmlParserAPIs.jar MyJar.jar

              And here is the peculiar thing (since I am using Windows 2000):

              %JAVA_HOME\bin\java -jar MyJar.jar test.xml

              And it worked!!!

              You may try executing your jar by the above method. Else where in this forum, I had come across a posting that said that you have to rename any java.exe under c:\winnt\system32 directory to prevent this error.
              • 4. Re: NoClassDefFound when running programmatically created JAR
                843802
                Hi, Mr. Silly:

                I'm trying to create a JAR file programmatically and I also have problems when I want to execute my application. I use the following code:
                Manifest manifest = new Manifest();
                manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
                manifest.getMainAttributes().putValue("Main-Class", "com.xxx.util.Xxx");
                    
                jarout = new JarOutputStream(new FileOutputStream("Xxx.jar"), manifest);
                    
                int iClassesFilesSize = classFiles.size();
                for(int i=0; i<classFiles.size(); i++) {
                    CRC32 crc32 = new CRC32();            
                               
                    File f = (File)classFiles.get(i);
                    byte[] data = readFile(f);
                    crc32.update(data, 0, data.length);
                   
                    String sNameWithPath = f.getAbsolutePath();
                    sNameWithPath = sNameWithPath.substring(sNameWithPath.indexOf("classes")+8);
                   
                    JarEntry jarEntry = new JarEntry(sNameWithPath);
                    jarEntry.setSize(data.length);
                    jarEntry.setTime(f.lastModified());
                    jarEntry.setCrc(crc32.getValue());
                   
                    jarout.putNextEntry(jarEntry);
                    jarout.write(data, 0, data.length);
                    jarout.flush();
                    jarout.closeEntry();
                }
                jarout.flush();
                jarout.finish();
                Everytime I try to execute my application with:
                java.exe -jar Xxx.jar
                I get the following message:
                Exception in thread "main" java.lang.NoClassDefFoundError: com/xxx/util/Xxx
                The JAR file seems to be perfect. WinZip can open it and if I descompress it with folder names , the CLASS files result to be in the right place with the right names.

                What is it going wrong?

                Thanks in advance.
                • 5. Re: NoClassDefFound when running programmatically created JAR
                  843802
                  Manifest m=new Manifest();
                  m.getMainAttributes().putValue("Manifest-Version",
                  , "1.0");
                  m.getMainAttributes().putValue("Main-Class",
                  , "MyClass");
                  Hi!Your solution is marvelous and solve my headache:)
                  However, I'm wondering why I got an empty Manifest file
                  if I slightly modify the code:
                  Manifest mf=new Manifest();
                  Attributes attrs=mf.getMainAttributes();
                  attrs.putValue("someKey","someValue");

                  I'll appreciate for any suggestion:>
                  • 6. Re: NoClassDefFound when running programmatically created JAR
                    843802
                    Hi Mr_Silly,

                    I am facing exactly same problem (NoClassDefFound when running programmatically created JAR). I went through all notes on this issue. I have a question for you. If you have noticed anything on this let me know your valuable comments.

                    1. You have mentioned to add the manifest file with main-class information. But when I create the jar using the sun's jar utility (jar.exe) with <I>-cvf </I> option, it does NOT add the main-class entry in the Manifest file and the jar still works fine. So I should expect my application (Programmatically creation of JAR) to generate a jar exactly like the jar create using sun's jar utility.

                    Any comment?

                    2. I used the following code to displayed the jar entry list:

                    JarDir.java
                    import java.io.*;
                    import java.util.*;
                    import java.util.jar.*;
                    
                    public class JarDir {
                         public static void main (String args[])
                             throws IOException {
                           if (args.length != 1) {
                             System.out.println("Please provide a JAR filename");
                             System.exit(-1);
                           }
                           JarFile jarFile = new JarFile(args[0]);
                           Enumeration enum = jarFile.entries();
                           while (enum.hasMoreElements()) {
                             process(enum.nextElement());
                           }
                         }
                    
                         private static void process(Object obj) {
                           JarEntry entry = (JarEntry)obj;
                           String name = entry.getName();
                           long size = entry.getSize();
                           long compressedSize = entry.getCompressedSize();
                           System.out.println(name + "\t" + size + "\t" + compressedSize);
                         }
                       }
                    I checked for the jar file created through the program as well as jar.exe
                    Here is the output:

                    a. Output for Jar file created through program:
                    com\test1\JarDir.class  1242    745
                    com\test2\JarRead.class 1121    677
                    b. Output for Jar file created through jar.exe:
                    com/    0       0
                    com/test1/      0       0
                    com/test1/JarDir.class  1242    745
                    com/test2/      0       0
                    com/test2/JarRead.class 1121    677
                    As you have seen here the the jar created using jar.exe contains additional entries for folder as well. Why such difference?

                    In your application also do you see such differences? If not, could you please forward me your code of creating jar file.

                    Any idea? Your feedback will be very much appreciated.

                    Thanks in advance,
                    • 7. Re: NoClassDefFound when running programmatically created JAR
                      843802
                      Hi,

                      I had the same problem.
                      The solution I finally found was: The path provided to the JarEntry cannot not contain any backslashs. Only slahes seem to work.

                      Hope this helps.

                      Georg
                      • 8. Re: NoClassDefFound when running programmatically created JAR
                        843804
                        I don't know if anyone is still reading this, but this last answer given by GeorgMWenzel solved the problem for me - after having spent several hours with trial and error and without any clue what was going wrong.

                        Thank you so much!

                        (...but the java documentation sucks at this topic! How should anyone know this??)