简体   繁体   中英

How to attach file to jar that can be edited inside this jar?

I am making a program that works with MySQL database,for now i store URL, login, password etc as public static String . Now i need to make it possible to work on another computer, so database adress will vary, so i need a way to edit it inside programm and save. I would like to use just external txt file, but i don't know how to point it's location.

I decided to make it using Property file, i put it in src/res folder. It work correct while i'm trying it inside Intellij Idea, but when i build jar (artifact) i get java.io.FileNotFoundException

I tried two ways: This one was just copied private String getFile(String fileName) {

 StringBuilder result = new StringBuilder(""); //Get file from resources folder ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource(fileName).getFile()); System.out.println(file.length()); try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); result.append(line).append("\\n"); } scanner.close(); } catch (IOException e) { e.printStackTrace(); } return result.toString(); } System.out.println(obj.getFile("res/cfg.txt"));</code> And second one using Properties class: try(FileReader reader = new FileReader("src/res/cfg.txt")) { Properties properties = new Properties(); properties.load(reader); System.out.println(properties.get("password")); }catch (Exception e) { e.printStackTrace(); System.out.println(e); }

StringBuilder result = new StringBuilder(""); //Get file from resources folder ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource(fileName).getFile()); System.out.println(file.length()); try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); result.append(line).append("\\n"); } scanner.close(); } catch (IOException e) { e.printStackTrace(); } return result.toString(); } System.out.println(obj.getFile("res/cfg.txt"));</code> And second one using Properties class: try(FileReader reader = new FileReader("src/res/cfg.txt")) { Properties properties = new Properties(); properties.load(reader); System.out.println(properties.get("password")); }catch (Exception e) { e.printStackTrace(); System.out.println(e); }

 StringBuilder result = new StringBuilder(""); //Get file from resources folder ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource(fileName).getFile()); System.out.println(file.length()); try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); result.append(line).append("\\n"); } scanner.close(); } catch (IOException e) { e.printStackTrace(); } return result.toString(); } System.out.println(obj.getFile("res/cfg.txt"));</code> And second one using Properties class: try(FileReader reader = new FileReader("src/res/cfg.txt")) { Properties properties = new Properties(); properties.load(reader); System.out.println(properties.get("password")); }catch (Exception e) { e.printStackTrace(); System.out.println(e); }

In both ways i get java.io.FileNotFoundException . What is right way to attach config file like that?

Since the file is inside a .JAR, it can't be accessed via new File() , but you can still read it via the ClassLoader :

Properties properties = new Properties();
try (InputStream stream = getClass().getResourceAsStream("/res/cfg.txt")) {
    properties.load(stream);
}

Note that a JAR is read-only. So this approach won't work.

If you want to have editable configuration, you should place your cfg.txt outside the JAR and read it from the filesystem. For example like this:

Properties properties = new Properties();
File appPath = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile();
try (InputStream stream = new FileInputStream(new File(appPath, "cfg.txt"))) {
    properties.load(stream);
}

There are multiple places your can place your configuration options, and a robust deployment strategy will utilize some (or all) of the following techniques:

  • Storing configuration files in a well known location relative to the user's home folder as I mentioned in the comments. This works on Windows ( C:\\Users\\efrisch ), Linux ( /home/efrisch ) and Mac ( /Users/efrisch )

     File f = new File(System.getProperty("user.home"), "my-settings.txt"); 
  • Reading environment variables to control it

     File f = new File(System.getenv("DEPLOY_DIR"), "my-settings.txt"); 
  • Using a decentralized service such as Apache ZooKeeper to store your database settings

  • Use Standalone JNDI (or the JNDI built-in to your deployment target)

  • Use a Connection Pool

尝试将数据库凭据保存在环境变量中,然后按以下方式调用它们:

public static String myValue = System.getenv("ENVIRONMENT_VARIABLE_NAME"); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM