2017-01-02 9 views
2

私はDebain 8.0 - jessie(64ビット)を使用しています。シェルスクリプトを通してjarファイルを実行するときのLinux - IO例外

jarファイルをディレクトリ外からシェルスクリプトを使って実行しようとすると、IO例外が発生します。

ディレクトリ: "/ホーム/ rscedit"

ファイル: "データ(ディレクトリ)" "run.sh(ファイル)" "Webserver.jar(ファイル)"

私が実行しようとします " run.sh "/ home/rscedit"以外の場所から、私は私のjarファイルのIO例外に直面しています。

しかし、 "/ home/rscedit"から "run.sh"を実行しようとすると、正常に動作します。

起動時にシェルスクリプトを実行したいので、シェルスクリプトを "/ home/rscedit"外から実行する必要がありますか?

シェルスクリプト

#!/bin/sh 
java -jar -Xmx20480m /home/rscedit/Webserver.jar 
read –n1 

私のシェルスクリプト

java.nio.file.NoSuchFileException: ./data/log/ipn.log.lck 
     at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) 
     at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) 
     at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) 
     at sun.nio.fs.UnixFileSystemProvider.newFileChannel(UnixFileSystemProvider.java:177) 
     at java.nio.channels.FileChannel.open(FileChannel.java:287) 
     at java.nio.channels.FileChannel.open(FileChannel.java:335) 
     at java.util.logging.FileHandler.openFiles(FileHandler.java:459) 
     at java.util.logging.FileHandler.<init>(FileHandler.java:326) 
     at org.displee.utilities.logging.LogFactory.loadFileLogger(LogFactory.java:44) 
     at org.displee.utilities.logging.LogFactory.<clinit>(LogFactory.java:19) 

LogFactory.java

package org.displee.utilities.logging; 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.StringWriter; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.logging.*; 

public class LogFactory { 

    private static final String FORMAT = "%1$td-%1$tm-%1$tY %1$tH:%1$tM:%1$tS %4$s %2$s - %5$s%6$s%n"; 

    private static final Map<String, Logger> MAP = new HashMap<>(); 

    static { 
     try { 
      loadFileLogger("ipn", "./data/log/ipn.log"); 
      loadFileLogger("error", "./data/log/error.log"); 

      Logger logger = Logger.getLogger("console"); 
      logger.setUseParentHandlers(false); 
      ConsoleHandler ch = new ConsoleHandler(); 
      ch.setFormatter(new ConsoleFormatter()); 
      ch.setLevel(Level.ALL); 
      logger.addHandler(ch); 
      register(logger.getName(), logger); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void register(String name, Logger logger) { 
     MAP.putIfAbsent(name, logger); 
    } 

    public static Logger get(String name) { 
     return MAP.get(name); 
    } 

    private static Logger loadFileLogger(String name, String path) throws IOException { 
     Logger logger = Logger.getLogger(name); 
     FileHandler fh = new FileHandler(path, true); 
     fh.setFormatter(new ConsoleFormatter()); 
     logger.addHandler(fh); 
     logger.setUseParentHandlers(false); 
     register(name, logger); 
     return logger; 
    } 

    private static class ConsoleFormatter extends Formatter { 
     @Override 
     public synchronized String format(LogRecord record) { 
      Date date = new Date(); 
      date.setTime(record.getMillis()); 
      String source; 
      if (record.getSourceClassName() != null) { 
       source = record.getSourceClassName(); 
       if (record.getSourceMethodName() != null) { 
        source += " " + record.getSourceMethodName(); 
       } 
      } else { 
       source = record.getLoggerName(); 
      } 
      String message = formatMessage(record); 
      String throwable = ""; 
      if (record.getThrown() != null) { 
       StringWriter sw = new StringWriter(); 
       PrintWriter pw = new PrintWriter(sw); 
       pw.println(); 
       record.getThrown().printStackTrace(pw); 
       pw.close(); 
       throwable = sw.toString(); 
      } 
      return String.format(FORMAT, 
        date, 
        source, 
        record.getLoggerName(), 
        "LOG", 
        message, 
        throwable); 
     } 
    } 

} 

私は私のシェルスクリプトを実行するために使用するコマンドを実行するときに私が取得エラー

exec /home/rscedit/run.sh 

編集:私のデータマップはログファイルだけでなく、ウェブサイトファイルのようなものも含んでいます。

答えて

3

あなたのJavaプログラムは作業ディレクトリに敏感であるようです。私が知っている最も簡単な解決策は、Javaの、このような何かに

loadFileLogger("ipn", "./data/log/ipn.log"); 
loadFileLogger("error", "./data/log/error.log"); 

(とどこでもあなたはパターンを持っている)(この

java -jar -Xmx20480m /home/rscedit/Webserver.jar 

(cd /home/rscedit ; java -jar -Xmx20480m Webserver.jar) 

それとも変更変更します$HOMEを基準にする)、

loadFileLogger("ipn", new File(System.getProperty("user.home"), 
     "data/log/ipn.log").getPath()); 
loadFileLogger("error", new File(System.getProperty("user.home"), 
     "data/log/error.log").getPath()); 
+0

これは、linuxがバックグラウンドでシェルスクリプトを実行しようとしたときにも動作しますか? – Displee

+0

@Displeeはい。しかし、私は別のオプションを追加しました。相対パスをハードコーディングする代わりに 'user.home'に相対的なパスを作ることです。 –

+0

実際のログフレームワークと同じようにすることをお勧めします。これらのファイルパスとログ定義のための個別の設定ファイルがあります。またはそれが多すぎる場合は、stdout/stderrにログオンし、起動時にそれらをリダイレクトしてください。 – eis

関連する問題