2015-02-02 3 views
0

Я хочу, чтобы java искал файл .properties в той же папке с запущенным jar. Как я могу это сделать, и как я могу определить, если приложение работает в IDE или в качестве явного файла флягиКак получить путь jar во время выполнения

+0

Не так уж большой подход.Вы должны либо 1) поместить свойства в файл jar, либо 2) поместить свойства где-то относительно текущего рабочего каталога (возможно, изменив cwd перед запуском jar) или 3) поместить свойства в одну и ту же хорошо известную (hardcoded или настраивается по окружению) location (think /etc/myapp/config.props) – Thilo

+0

Но если вам нужно: http://stackoverflow.com/questions/320542/how-to-get-the-path-of-a-running- jar-file? rq = 1 – Thilo

+0

Есть способ, это довольно хакерский, дай мне пару минут, и я найду его среди своих файлов и отправлю ответ. –

ответ

0

вы можете получить доступ к этому файлу (если он находится в вашем пути к классам) с помощью:

Paths.get(this.getClass().getResource("file.properties").toURI()); 
+1

Наверное, не на пути к классам. – Thilo

0

Во-первых у меня есть сказать, что это по своей сути плохая практика, хотя жизнь часто не идеальна, и иногда нам приходится кататься с плохими проектными ударами.

Это класс я набрался для любимого проекта шахты, что требуется такая функциональность:

public class ArbitraryPath { 

    private static Logger logger = LogManager.getLogger("utility"); 

    private static boolean isRunFromJar = false; 

    public static String resolveResourceFilePath(String fileName, String folderName, Class<?> requestingClass) throws URISyntaxException{ 
     // ARGUMENT NULL CHECK SAFETY HERE 
     String fullPath = requestingClass.getResource("").toURI().toString(); 
     isRunFromJar = isRunFromJar(fullPath); 
     String result = ""; 

     if(!isRunFromJar){ 
      result = trimPathDownToProject(requestingClass.getResource("").toURI()); 
     } 
     result = result+folderName+"/"+fileName+".properties"; 

     return result; 
    } 

    private static String trimPathDownToProject(URI previousPath){ 
     String result = null; 

     while(!isClassFolderReached(previousPath)){ 
      previousPath = previousPath.resolve(".."); 
     } 
     previousPath = previousPath.resolve(".."); 
     result = previousPath.getPath(); 
     return result; 
    } 

    private static boolean isClassFolderReached(URI currentPath){ 
     String checkableString = currentPath.toString(); 
     checkableString = checkableString.substring(0,checkableString.length()-1); 
     checkableString = checkableString.substring(checkableString.lastIndexOf("/")+1,checkableString.length()); 
     if(checkableString.equalsIgnoreCase("bin")){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    private static boolean isRunFromJar(String fullPath) throws URISyntaxException{ 
     String solidClassFolder = "/bin/"; 
     String solidJarContainer = ".jar!"; 
     if(!fullPath.contains(solidClassFolder)){ 
      if(fullPath.contains(solidJarContainer)){ 
       return true; 
      } else { 
       logger.error("Requesting class is not located within a supported project structure!"); 
       throw new IllegalArgumentException("Requesting class must be within a bin folder!"); 
      } 
     } else { 
      return false; 
     } 
    } 

} 

я думаю немного объяснить в порядке ...

В целом это будет пытаться решить путь к файлу свойств, который находится в произвольном проекте. Это означает, что класс ArbitraryPath не нужно размещать в том же проекте, что и файл свойств, что очень удобно, если вы хотите отделить, например, тесты JUnit в отдельном проекте. Он будет определять проект на основе класса, который вы ему даете, класс должен быть в том же проекте, что и файл свойств, который вы пытаетесь найти.

Так что прежде всего он получает путь класса вы дали его в этой строке:

String fullPath = requestingClass.getResource("").toURI().toString(); 

Затем он проверяет, является ли этот класс в файле JAR или, если он выполнен из IDE , Это делается путем проверки того, содержит ли путь «/ bin /», который обычно означает, что он выполняется из среды IDE или «.jar!». что обычно означает, что оно выполняется из JAR. Вы можете изменить метод, если у вас есть другая структура проекта.

Если определено, что это NOT запустите JAR, тогда мы обрезаем путь до папки проекта, идем назад по пути, пока не дойдем до папки BIN. Опять же, измените это, если ваша структура проекта отклоняется от стандарта.

(если мы решим, что это IS запустить из файла JAR, то мы ничего не обрезать, так как мы уже получили путь к папке базы.)

После этого мы извлечь путь в папку проекта, чтобы мы добавили имя папки (если она есть), где находится файл свойств, и добавьте имя файла и расширение файла свойств, который мы хотим найти.

Мы возвращаем этот путь. Затем мы можем использовать этот путь в InputStream, как например:

FileInputStream in = new FileInputStream(ArbitraryPath.resolveResourceFilePath("myPropertiesFile", "configFolder", UserConfiguration.class)); 

Который восстановит myPropertiesFile.properties в папке myConfiguration в папке проекта, где UserConfiguration.class находится.

Обратите внимание: этот класс предполагает, что у вас стандартная конфигурация проекта. Не стесняйтесь приспосабливать его к вашим потребностям и т. Д.

Также это действительно хакерский и грубый способ сделать это.

-1
String absolutePath = null; 
try { 
    absolutePath = (new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath())).getCanonicalPath(); 
    absolutePath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator))+File.separator; 
} catch (URISyntaxException ex) { 
    Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); 
} catch (IOException ex) { 
    Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); 
} 
Смежные вопросы