Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchMethodError when deployed on linux

I have the following code that reads from a file:

private static void writeLogs(String filePath, PrintWriter writer)throws ServletException, IOException {

    String fullFilePath = AppConfig.getAppDir()+"/auditlogs/"+filePath+".log";
    System.out.println("loading log files from --> "+fullFilePath);

    BufferedReader br = new BufferedReader(new FileReader(fullFilePath));
    try {
        StringBuilder sb = new StringBuilder();
        String line;
        List<String> tmp = new ArrayList<String>();
        do {
            line = br.readLine();
            tmp.add(line);

        }while (line != null);
        for(int i=tmp.size()-1;i>=0;i--) {
            if(tmp.get(i)!=null){
                sb.append(tmp.get(i));
                sb.append(System.lineSeparator());
            }
        }
        String logs = sb.toString();
        writer.write(logs);
    } finally {
        br.close();
    }
}

This works as expected when I deploy on tomcat server on windows. When I try to the same on linux, the files don't get read. On inspecting the tomcat log file I see:

SEVERE: Servlet.service() for servlet ReadLogsServlet threw exception
java.lang.NoSuchMethodError: java.lang.System.lineSeparator()Ljava/lang/String;
    at com.ericsson.ims.web.servlet.ReadLogsServlet.writeLogs(ReadLogsServlet.java:53)
    at com.ericsson.ims.web.servlet.ReadLogsServlet.doGet(ReadLogsServlet.java:26)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)

The error occurs due to System.lineSeparator()but when I check the javadoc, it says:

Returns the system-dependent line separator string. It always returns the same value - the initial value of the system property line.separator.

On UNIX systems, it returns "\n"; on Microsoft Windows systems it returns "\r\n".

Can anyone explain why this doesn't work and how to fix so it will work on multiple platforms?

like image 888
Sionnach733 Avatar asked Mar 07 '14 11:03

Sionnach733


3 Answers

It seems that you are not using the same version of Java between Linux and Windows.

As you can see in the javadoc, System.lineSeparator() doesn't exists in java < 7.

So, if you want to get the line separator on java < 7, you have to use:

System.getProperty("line.separator")
like image 60
Florent Bayle Avatar answered Sep 28 '22 16:09

Florent Bayle


It seems that you are running different JDK versions on Windows and Linux.

  • On Windows the JDK is 7 which has System.lineSeparator() method defined.
  • The same method does not exist in the previous JDK verions (check System class in Java 6) which is running on your Linux box.

For the backward compatible code use System.getProperty("line.separator").

like image 40
Santosh Avatar answered Sep 28 '22 16:09

Santosh


As others pointed out there is an issue with the versions. I would dare to say that merely changing the JVM is not enough. Your program could check for the expected version at startup to avoid such issues in the future:

String runtimeName = System.getProperty("java.runtime.name");
String runtimeVersion = System.getProperty("java.runtime.version");
... check if JVM is the expected one, log some informative message if not ...

You can also do this for other settings (Locale ...) but those depend on the nature of your project. The idea is that a dead program is better than a crippled one (fail fast), another idea is that you should fix an issue once and for all (find bugs once). You can find more tips here: http://pragprog.com/the-pragmatic-programmer/extracts/tips

like image 27
Christophe Roussy Avatar answered Sep 28 '22 17:09

Christophe Roussy