Mam plik JAR, w którym cały mój kod jest archiwizowany do uruchomienia. Muszę uzyskać dostęp do pliku właściwości, który należy zmienić / edytować przed każdym uruchomieniem. Chcę zachować plik właściwości w tym samym katalogu, w którym znajduje się plik JAR. Czy w ogóle można powiedzieć Javie, aby pobrał plik właściwości z tego katalogu?
Uwaga: nie chcę przechowywać pliku właściwości w katalogu domowym ani przekazywać ścieżki do pliku właściwości w argumencie wiersza poleceń.
java
properties
Neil
źródło
źródło
user.home
. Podczas sprawdzania pliku najpierw sprawdź istnienie zmieniony plik w systemie plików, a jeśli nie istnieje, załaduj plik domyślny. " BTW „Nie chcę…” To, czego chcesz, jest mniej ważne niż to, co działa i jest praktyczne. Przechowywanie aplikacji. ustawienia w katalogu aplikacji są zdecydowanie odradzane zarówno przez Oracle, jak i MS (i prawdopodobnie inne).Odpowiedzi:
Tak więc chcesz traktować swój
.properties
plik w tym samym folderze co główny / uruchamialny plik jar, a nie jako zasób głównego / uruchamialnego pliku jar. W takim przypadku moje własne rozwiązanie wygląda następująco:Po pierwsze: architektura pliku programu powinna wyglądać następująco (zakładając, że głównym programem jest main.jar, a jego głównym plikiem właściwości jest main.properties):
Dzięki tej architekturze można modyfikować dowolną właściwość w pliku main.properties za pomocą dowolnego edytora tekstu przed lub w trakcie działania pliku main.jar (w zależności od bieżącego stanu programu), ponieważ jest to tylko plik tekstowy. Na przykład plik main.properties może zawierać:
app.version=1.0.0.0 app.name=Hello
Tak więc, kiedy uruchamiasz swój główny program z jego katalogu głównego / podstawowego, zwykle uruchamiasz go w następujący sposób:
lub od razu:
W pliku main.jar musisz utworzyć kilka metod narzędziowych dla każdej właściwości znalezionej w pliku main.properties; powiedzmy, że
app.version
właściwość będzie miałagetAppVersion()
następującą metodę:/** * 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; }
W dowolnej części programu głównego, która potrzebuje
app.version
wartości, wywołujemy jej metodę w następujący sposób:String version = null; try{ version = getAppVersion(); } catch (IOException ioe){ ioe.printStackTrace(); }
źródło
./
folderze głównym (na tym samym poziomie katalogu), co opisałem w architekturze organizacji plików. (zgodnie z wymogami oryginalnego plakatu)java -jar build/main.jar
, musisz umieścić plik właściwości również wbuild
folderze, aby znajdował się na tym samym poziomie katalogu co jar.java -jar path/to/jar/file
. Ale znalazłem rozwiązanie w innym pytaniu:String path = ClassLoader.getSystemClassLoader().getResource(".").getPath() + "/main.properties";
Zrobiłem to w inny sposób.
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(); }
źródło
Zawsze występuje problem z dostępem do plików w katalogu plików z pliku jar. Podanie ścieżki klas w pliku jar jest bardzo ograniczone. Zamiast tego spróbuj użyć pliku bat lub pliku sh, aby uruchomić program. W ten sposób możesz określić ścieżkę klasy tak, jak chcesz, odwołując się do dowolnego folderu w dowolnym miejscu w systemie.
Sprawdź także moją odpowiedź na to pytanie:
tworzenie pliku .exe dla projektu java zawierającego sqlite
źródło
Mam podobny przypadek: chcę, aby mój
*.jar
plik miał dostęp do pliku w katalogu obok wspomnianego*.jar
pliku. Zapoznaj się również z TĄ ODPOWIEDZIĄ .Moja struktura plików to:
Jestem w stanie załadować plik (powiedzmy
some.txt
) do InputStream wewnątrz*.jar
pliku z następującymi elementami :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()); }
Następnie zrób, co chcesz, z
stream
źródło
Mam przykład robienia obu przez classpath lub z zewnętrznej konfiguracji z 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
źródło
To działa dla mnie. Załaduj plik właściwości z
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); });
Upewnij się, że
java.properties
jest tocurrent directory
. Możesz po prostu napisać mały skrypt startowy, który przełączy się do odpowiedniego katalogu wcześniej, na przykład#! /bin/bash scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $scriptdir java -jar MyExecutable.jar cd -
W swoim projekcie po prostu umieść
java.properties
plik w katalogu głównym projektu, aby kod działał również z twojego IDE.źródło
Tutaj, jeśli wspomnisz
.getPath()
, to zwróci ścieżkę do Jar i myślę, że będziesz potrzebować jego rodzica, aby odnosił się do wszystkich innych plików konfiguracyjnych umieszczonych w jar. Ten kod działa w systemie Windows. Dodaj kod w klasie głównej.File jarDir = new File(MyAppName.class.getProtectionDomain().getCodeSource().getLocation().getPath()); String jarDirpath = jarDir.getParent(); System.out.println(jarDirpath);
źródło