Jump to content
Excelsior Forums
Sign in to follow this  
roytsganda

Jet-compiled exe gives NullPointerException in W98

Recommended Posts

Problem:

We have a large Java program that for some functions gives Null Pointer Exceptions (NPEs) when run on Windows 98 in its Jet-compiled form but gives no exceptions when run in Java with identical data.  We are using Jet 3.6, but we have tried this same program with a trial version of Jet 3.7 and that's the same.

Investigation:

We wrote a much smaller Java program that simulates one of the troublesome functions in the large program. The program traverses a given directory and counts the number of files and directories that have been visited.  We compiled the program using Jet 3.6 MP3 Pro. We JetPack the program and ran it on a Windows 98 installation.  The same problems do not happen in Windows XP.

We tested the program with a directory containing a hierarchy of 1,700 directories to a depth of eight levels and with a total of 90,000 files. This test program never fails when run in Java directly.

We tried Jet Heap sizes of 64MB, 96MB, 128MB, 256MB and 512MB.  In combination with these Heap sizes, we made compilations with Stack sizes of 400K, 878K, 1M and 2M.

We tested all combinations with the same test data (the 1,700 directories mentioned above) to give a 5 x 4 matrix (Heap size x stack size) of results - attached as Jet tests.jpg.  For each heap size at least one stack size would result in NPEs, and sometimes two stack sizes resulted in NPEs.

The tests run directly in Java used a Heap Size of 128MB.

Results:

The test program gives the exceptions numbered [1] to [6] below.

For [1], we are sure that it is not our programmatical error because we never have the error when running the Java version.

For [2], again, it is not something that we did wrong with the code.  getAbsolutePath() should never give a NullPointerException , even if the file object does not exist in the filesystem.

For [3], the index is not in our control, we were just calling File.getName(). For [4], [5] and [6], we are sure that the elements we are looking for exist in those Arraylist and AbstractList and we did not encounter these exceptions in the Java version.

Our conclusion:

The large Java program that 1st brought this problem, to our notice does similar file operations to the test program and not only it will give NullPointerExceptions, it will also give NoSuchElementExceptions and ClassCastException when we use Java Collections.  Clearly this Sun Java library should never give exceptions!

We suspect that the runtime environment of Jet is somehow corrupting the data structures in memory and giving us these strange kinds of exception.

I will post Java code as a reply to this.  Can anyone help, please?  

Thanks

[1]

java.lang.NullPointerException

at java.util.ArrayList.add(Unknown Source)

at JetTest01.GetFileInfo(JetTest01.java:132)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.ShowFileInfo(JetTest01.java:110)

at JetTest01.main(JetTest01.java:54)

[2]

java.lang.NullPointerException

at java.io.Win32FileSystem.resolve(Unknown Source)

at java.io.File.getAbsolutePath(File.class:0)

at JetTest01.GetFileInfo(JetTest01.java:132)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.GetFileInfo(JetTest01.java:137)

at JetTest01.ShowFileInfo(JetTest01.java:110)

at JetTest01.main(JetTest01.java:54)

[3]

java.lang.StringIndexOutOfBoundsException: String index out of range:

-143231424

at java.lang.String.substring(Unknown Source)

at java.lang.String.<unknown>(Unknown Source)

at java.io.File.getName(Unknown Source)

[4]

java.lang.NullPointerException

at java.util.ArrayList.get(ArrayList.java:322)

[5]

java.util.NoSuchElementException

at java.util.AbstractList$Itr.next(Unknown Source)

[6]

java.lang.NullPointerException

at java.util.ArrayList.get(Unknown Source)

at java.util.AbstractList$Itr.next(Unknown Source)

Share this post


Link to post
Share on other sites

Here's the source code for test prog mentioned in the original post

---------------------------------------------------------------------

import org.apache.log4j.Logger;

import java.io.BufferedReader;

import java.io.File;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.Iterator;

public class JetTest01 {

   static final Logger log = Logger.getLogger(JetTest01.class);

   static int fileCount = 0;

   static int deepestLevel = 0;

   private static final int ONE_MEGA_BYTE = 1048576;

   static {

       File b = new File("b");

       File absoluteFile = b.getAbsoluteFile();

       System.out.println("absoluteFile = " + absoluteFile);

   }

   public static void main(String[] args) {

       try {

           log.info("JetTest01");

           for (int i = 0; i < args.length; i++) {

               String arg = args;

               log.debug("arg[" + i + "]\t" + arg);

           }

           if (args.length == 2) {

               String directory = args[0];

               log.info("directory\t" + directory);

               // Get Heap Size

               float heap = (float) Runtime.getRuntime().maxMemory() /

ONE_MEGA_BYTE;

               log.info("Maximum Heap Size (MB)\t" + heap);

               // Get Number of objects created at start

               int objectCount = 20000;

               try {

                   objectCount = Integer.parseInt(args[1]);

               } catch (NumberFormatException e) {

                   log.info(e.getMessage());

               }

               log.info(objectCount + "\tobjects");

               byte[] array = new byte[objectCount];

               for (int i = 0; i < objectCount; i++) {

                   array = 0;

               }

               log.info("Scanning");

               JetTest01 tc = new JetTest01();

               tc.ShowFileInfo(directory);

               log.info("Completed");

               log.info("f/d recursed\t" + fileCount);

               log.info("Deepest Level\t" + deepestLevel);

               //throwExp();

           } else {

               BufferedReader console = new BufferedReader(new

InputStreamReader(System.in));

               try {

                   log.info("You must input the directory that you want to

test. Press enter to quit.");

                   console.readLine();

               } catch (Exception e) {

                   log.error("Error details\t", e);

               }

           }

       } catch (Throwable e) {

           log.error("FAILED");

           log.error("Error details\t", e);

/*

               log.error("Manually extracting nested causes and

traces....");

               Throwable current = e;

               do {

                   log.error(current);

                   StackTraceElement[] stackTrace =

current.getStackTrace();

                   for (int i = 0; i < stackTrace.length; i++) {

                       StackTraceElement stackTraceElement = stackTrace;

                       log.error(stackTraceElement);

                   }

                    log.error("");

                   current = current.getCause();

               } while (current != null);

*/

       } finally {

           log.info("done");

       }

   }

   private static void throwExp() {

       RuntimeException a = new RuntimeException("a");

       RuntimeException b = new RuntimeException("b", a);

       RuntimeException c = new RuntimeException("c", B);

       RuntimeException d = new RuntimeException("d", c);

       RuntimeException e = new RuntimeException("e", d);

       RuntimeException f = new RuntimeException("f", e);

       RuntimeException g = new RuntimeException("g", f);

       throw g;

   }

   public void ShowFileInfo(String pathname) {

       if (!new File(pathname).exists()) {

           throw new IllegalArgumentException(pathname + " cannot be

found.");

       }

       ArrayList fileInfo = new ArrayList();

       GetFileInfo(fileInfo, pathname, 1);

       for (Iterator it = fileInfo.iterator(); it.hasNext();) {

           it.next();

           fileCount++;

       }

   }

   private void GetFileInfo(ArrayList fileInfo, String filePath, int level)

{

       if (level > deepestLevel) deepestLevel = level;

       File file = new File(filePath);

       String preSpace = new String();

       for (int i = 1; i < level; i++)

           preSpace = preSpace.concat(" ");

       if (file.isDirectory())

           fileInfo.add(preSpace + "+" + file.getAbsolutePath() + "\\" +

file.getName());

       else

           fileInfo.add(preSpace + "-" + file.getAbsolutePath() + "\\" +

file.getName());

       if (file.isDirectory()) {

           String[] fileList = file.list();

           for (int i = 0; i < fileList.length; i++) {

               GetFileInfo(fileInfo, file.getAbsolutePath() + "\\" +

fileList, level + 1);

           }

       }

   }

}

Share this post


Link to post
Share on other sites

Excelsior sent me a Hotfix for Jet pro edition 3.6.  (A fix for 3.7 is available too).

With the test program in my original post, this now works without NPEs.  We have now recompiled our product (see www.topicscape.com) with it and so far have not experienced any NullPointerExceptions under the normal operating conditions that produced them before with the JET version of our software.  We have also conducted some stress tests and these too seem to be operating normally.

Our thanks to Excelsior for their help in overcoming this problem.  It took a while, but they (and we) kept at it until it was solved.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×