24 September 2009

Read files in Java

The source code below searches for all XML files in the specified folder and recursively searches in subfolders. The files are read as bytes and transformed to String. In this specific example the main goal is to read the entire file and transform it in a String to be processed, so there is not need to read the file line by line, what is probably more time consuming.


       /**
        * Main method used to test this class to read message in XML format from the
        * specified folder and to process it.
        * When launching this method a parameter can be used to specify the folder where
        * to search the files.
        *
        * @param args The folder name can be specified, otherwise the current folder is used.
        */
       public static void main(String[] args) {
              String folder = ".";
              if (args.length > 0 && args[0] != null && args[0].length() > 0) {
                     folder = args[0];
              }

              System.out.println("Searching in folder " + folder);
              findFiles(new File(folder));
       }


       /**
        * Finds all XML messages in the specified path, including sub-folders,
        *and process the file.
        *
        * @param file File to be read and transform in String.
        */
       private static void findFiles(File file) {
              File listFiles[] = file.listFiles();

              String type = "xml"; // Searches only for XML files
              int fileIndex = 0;

              while (fileIndex < listFiles.length) {
                     File currentFile = listFiles[fileIndex];
                     if (currentFile.isDirectory()) {
                           findFiles(currentFile); // Recursively find files in subfolders
                     } else if (currentFile.isFile() && currentFile.getName().endsWith(type)) {
                           try {
                                  System.out.println(currentFile.getPath()
                                                     + "length" + currentFile.length());
                                  SendMesg(getFileAsBytes(currentFile)); // Process file
                           } catch (IOException e) {
                                  e.printStackTrace();
                           }
                     }
                     fileIndex++;
              }

       }


       /**
        * Reads the specified file as an array of bytes and transforms it in a String.
        *
        * @param file File to be read and transform in String.
        * @return The message in String format.
        */
       private final static String getFileAsBytes(File file) throws IOException {
              BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
              byte[] bytes = new byte[(int) file.length()];
              bis.read(bytes);
              bis.close();
              return new String(bytes);
       }

22 September 2009

Eclipse "Source not found" error when debugging


When debugging a project in Eclipse some times the error ‘Source not found’ is thrown with the option ‘EditSourceLookup Path’ to specify the path to the source code. Even having the correct path for the source code defined the error still happens.

In my case the error happened because Eclipse tried to find the source code for the JRE classes, however it was not defined in the path of my project. I solved it by adding the library for the JRE and adding the classpath variable as part of the path. There is also an option to add the JRE source code (‘Attach Source…’), so Eclipse finds the Java source code when needed.

This often happens when an exception is thrown, so Eclipse tries to continue debugging through the Java or external libraries code, what is normally not available.  Very common for NullPointerException.



17 September 2009

Exception in thread "main" java.lang.NoClassDefFoundError: ClassName

The exception "Exception in thread "main" java.lang.NoClassDefFoundError" normally happens when the class is not correctly defined in the classpath. However, it can also happens when incorrectly launched using java ClassName.class. Following are some scenarios when this problem can happen:

1. Class launched with .class file extension

When launching a class using java ClassName adding .class as part of the class name, this exception is thrown because java considers the name of the class as ClassName.class, so cannot find the class. See below an example.

Wrong

java ClassName.class

Following execption is thrown because java cannot find the class
"Exception in thread "main" java.lang.NoClassDefFoundError: ClassName"

Correct

java ClassName

In this case the class if found, so no exception is thrown.


2. jar file classpath

This error also happened when launching a jar file using java -jar ClassName as displayed in the exception below:


Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
        at com.sds.pev.util.ConfParamBase.(ConfParamBase.java:33)
        at SendMessageToTCPServer.main(SendMessageToTCPServer.java:19)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
        ... 2 more

This exception means that the Log4j jar files was not found. Even adding the jar to the Windows classpath this error was happening. The way how I solved the problem was adding the classpath tag in the Manifest file, as described below:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 11.3-b02 (Sun Microsystems Inc.)
Main-Class: SendMessageToTCPServer
Class-Path: log_log4j-1.2.15.jar

16 September 2009

[38000] Unknown throwable: (java.lang.ClassCastException)

My application is running a function in Informix which calls a jar file internally, but when executing the function I get the following error:


[Error Code: -937, SQL State: 38000] Unknown throwable: (java.lang.ClassCastException)

The jar file was installed using the function sqlj.install_jar with following procedure:


EXECUTE PROCEDURE sqlj.replace_jar ('file:/app_dev/tmp/SendMessage.jar', 'sendMsgJar');


Using this procedure the jar file is installed in Informix and copied to the /tmp folder.


After long investigation I identified in informix log file "jvp.log" that one class could not be found, so the error message was thrown. I checked the JVPCLASSPATH property in the ONCONFIG file and all the necessary jars were correctly defined, so apparently there was no reason for this error. After changing the JVPCLASSPATH I restarted Informix using the command "onmode -ky; oninit -v", so the new classpath would be loaded to memory. At this point the following message was displayed:


Reading configuration file '/app/informix/etc/onconfig'...Max length of 256 exceeded for configuration parameter JVPCLASSPATH


It means that in my case the error message happened because of the length of the classpath, which in Informix can't exceed 256 characters. After updating the JVPCLASSPATH and restarting the server the function worked properly.