すべてのコードが実行用にアーカイブされているJARファイルがあります。各実行前に変更/編集する必要があるプロパティファイルにアクセスする必要があります。プロパティファイルをJARファイルと同じディレクトリに保持したい。とにかくそのディレクトリからプロパティファイルを取得するようにJavaに指示するのですか?
注:プロパティファイルをホームディレクトリに保持したり、コマンドライン引数でプロパティファイルのパスを渡したりしたくありません。
すべてのコードが実行用にアーカイブされているJARファイルがあります。各実行前に変更/編集する必要があるプロパティファイルにアクセスする必要があります。プロパティファイルをJARファイルと同じディレクトリに保持したい。とにかくそのディレクトリからプロパティファイルを取得するようにJavaに指示するのですか?
注:プロパティファイルをホームディレクトリに保持したり、コマンドライン引数でプロパティファイルのパスを渡したりしたくありません。
回答:
したがって、.properties
同じフォルダーにあるファイルを、メイン/実行可能なjarのリソースとしてではなく、ファイルとして扱う必要があります。その場合、私自身の解決策は次のとおりです:
まず最初に、プログラムファイルのアーキテクチャは次のようになります(メインプログラムがmain.jarで、そのメインプロパティファイルがmain.propertiesであると想定)。
./ - the root of your program
|__ main.jar
|__ main.properties
このアーキテクチャでは、main.jarの実行前または実行中に(プログラムの現在の状態に応じて)、テキストエディターを使用してmain.propertiesファイルのプロパティを変更できます。たとえば、main.propertiesファイルには次のものが含まれる場合があります。
app.version=1.0.0.0
app.name=Hello
したがって、メインプログラムをroot / baseフォルダーから実行すると、通常は次のように実行されます。
java -jar ./main.jar
または、すぐに:
java -jar main.jar
main.jarで、main.propertiesファイルにあるすべてのプロパティに対していくつかのユーティリティメソッドを作成する必要があります。app.version
プロパティがgetAppVersion()
次のようなメソッドを持つとしましょう:
/**
* Gets the app.version property value from
* the ./main.properties file of the base folder
*
* @return app.version string
* @throws IOException
*/
import java.util.Properties;
public static String getAppVersion() throws IOException{
String versionString = null;
//to load application's properties, we use this class
Properties mainProperties = new Properties();
FileInputStream file;
//the base folder is ./, the root of the main.properties file
String path = "./main.properties";
//load the file handle for main.properties
file = new FileInputStream(path);
//load all the properties from this file
mainProperties.load(file);
//we have loaded the properties, so close the file handle
file.close();
//retrieve the property we are intrested, the app.version
versionString = mainProperties.getProperty("app.version");
return versionString;
}
app.version
値を必要とするメインプログラムの任意の部分で、次のようにそのメソッドを呼び出します。
String version = null;
try{
version = getAppVersion();
}
catch (IOException ioe){
ioe.printStackTrace();
}
./
ファイル構成アーキテクチャーで説明したものと同じルートフォルダー(同じディレクトリレベル)にjarファイルとプロパティファイルを配置する必要がある場合にのみ、設計どおりに機能します。(元のポスターで設定された要件による)
java -jar build/main.jar
あるように、プロパティファイルもbuild
フォルダに配置する必要があります。
java -jar path/to/jar/file
です。しかし、私は別の質問で解決策を見つけました:String path = ClassLoader.getSystemClassLoader().getResource(".").getPath() + "/main.properties";
別の方法でやった。
Properties prop = new Properties();
try {
File jarPath=new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String propertiesPath=jarPath.getParentFile().getAbsolutePath();
System.out.println(" propertiesPath-"+propertiesPath);
prop.load(new FileInputStream(propertiesPath+"/importer.properties"));
} catch (IOException e1) {
e1.printStackTrace();
}
jarファイルからファイルディレクトリのファイルにアクセスする場合、常に問題が発生します。jarファイルでのクラスパスの提供は非常に制限されています。代わりに、batファイルまたはshファイルを使用してプログラムを起動してみてください。このようにして、システム上の任意の場所にある任意のフォルダーを参照して、クラスパスを任意に指定できます。
また、この質問に対する私の答えを確認してください:
私は同様のケースがあります。私の*.jar
ファイルがそのファイルの隣のディレクトリにあるファイルにアクセスすることを望んでい*.jar
ます。この回答も参照してください。
私のファイル構造は:
./ - the root of your program
|__ *.jar
|__ dir-next-to-jar/some.txt
次のようにして、ファイル(たとえばsome.txt
)を*.jar
ファイル内のInputStream にロードできます。
InputStream stream = null;
try{
stream = ThisClassName.class.getClass().getResourceAsStream("/dir-next-to-jar/some.txt");
}
catch(Exception e) {
System.out.print("error file to stream: ");
System.out.println(e.getMessage());
}
次に、あなたがすることは何でもしてください stream
クラスパスまたはlog4j2.propertiesの外部構成から両方を実行する例があります
package org.mmartin.app1;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.LogManager;
public class App1 {
private static Logger logger=null;
private static final String LOG_PROPERTIES_FILE = "config/log4j2.properties";
private static final String CONFIG_PROPERTIES_FILE = "config/config.properties";
private Properties properties= new Properties();
public App1() {
System.out.println("--Logger intialized with classpath properties file--");
intializeLogger1();
testLogging();
System.out.println("--Logger intialized with external file--");
intializeLogger2();
testLogging();
}
public void readProperties() {
InputStream input = null;
try {
input = new FileInputStream(CONFIG_PROPERTIES_FILE);
this.properties.load(input);
} catch (IOException e) {
logger.error("Unable to read the config.properties file.",e);
System.exit(1);
}
}
public void printProperties() {
this.properties.list(System.out);
}
public void testLogging() {
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warn message");
logger.error("This is an error message");
logger.fatal("This is a fatal message");
logger.info("Logger's name: "+logger.getName());
}
private void intializeLogger1() {
logger = LogManager.getLogger(App1.class);
}
private void intializeLogger2() {
LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File(LOG_PROPERTIES_FILE);
// this will force a reconfiguration
context.setConfigLocation(file.toURI());
logger = context.getLogger(App1.class.getName());
}
public static void main(String[] args) {
App1 app1 = new App1();
app1.readProperties();
app1.printProperties();
}
}
--Logger intialized with classpath properties file--
[DEBUG] 2018-08-27 10:35:14.510 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.513 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.513 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.513 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.513 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.514 [main] App1 - Logger's name: org.mmartin.app1.App1
--Logger intialized with external file--
[DEBUG] 2018-08-27 10:35:14.524 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.525 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.525 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.525 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - Logger's name: org.mmartin.app1.App1
-- listing properties --
dbpassword=password
database=localhost
dbuser=user
これでうまくいきます。プロパティファイルをロードするcurrent directory
Properties properties = new Properties();
properties.load(new FileReader(new File(".").getCanonicalPath() + File.separator + "java.properties"));
properties.forEach((k, v) -> {
System.out.println(k + " : " + v);
});
ていることを確認し、それがjava.properties
ですcurrent directory
。次のように、前に正しいディレクトリに切り替える小さな起動スクリプトを書くだけです。
#! /bin/bash
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $scriptdir
java -jar MyExecutable.jar
cd -
プロジェクトでは、java.properties
このコードをIDEからも機能させるために、ファイルをプロジェクトルートに配置するだけです。
ここで言及.getPath()
すると、jarのパスが返されます。jarとともに配置された他のすべての構成ファイルを参照するには、その親が必要になると思います。このコードはWindowsで動作します。メインクラス内にコードを追加します。
File jarDir = new File(MyAppName.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String jarDirpath = jarDir.getParent();
System.out.println(jarDirpath);
user.home
。ファイルを確認するときは、最初にファイルシステム上の変更されたファイル。存在しない場合は、デフォルトのファイルをロードしてください。」 ところで 「私はしたくない..」あなたが望むものは、何が機能し実用的であるかほど重要ではありません。アプリを保存しています。アプリケーションディレクトリの設定は、OracleとMSの両方(おそらく他のユーザーも)が強く推奨していません。