2012-01-08 14 views
86

Tengo un archivo JAR donde todo mi código está archivado para ejecutarse. Tengo que acceder a un archivo de propiedades que debe modificarse/editarse antes de cada ejecución. Quiero mantener el archivo de propiedades en el mismo directorio donde está el archivo JAR. ¿Hay alguna forma de decirle a Java que recoja el archivo de propiedades de ese directorio?Leer archivo de propiedades fuera del archivo JAR

Nota: No quiero mantener el archivo de propiedades en el directorio de inicio ni pasar la ruta del archivo de propiedades en el argumento de línea de comando.

+0

Ver [esta respuesta] (http://stackoverflow.com/a/5052359/418556) - * "En lugar de almacenar el archivo 'predeterminado' dentro del tarro. Si se cambia, almacenar el archivo alterado en otro lugar. Un lugar común es un subdirectorio de 'user.home'. Al verificar el archivo, primero verifique la existencia de un archivo alterado en el sistema de archivos, y si no existe, cargue el archivo predeterminado. "* ** BTW ** *" No quiero ... "* Lo que es menos importante que lo que funciona y es práctico. El almacenamiento de la configuración de la aplicación en el directorio de la aplicación es fuertemente desaconsejado por Oracle y MS (y probablemente otros). –

+2

La razón por la que necesito mantener el archivo de propiedades en el directorio jar es que es mejor mantenerlos juntos cuando todo el directorio (incluidos el jar y la propiedad) se copia en otra máquina y ejecutar. – SoulMan

+0

Y si forzo al usuario a pasar la ruta del archivo de propiedad, entonces necesita cambiarlo cada vez que ejecuta el lote archivo de una máquina diferente – SoulMan

Respuesta

112

Por lo tanto, usted quiere tratar su archivo .properties en la misma carpeta que el principal jar/ejecutable como un archivo en lugar de como un recurso de la jar principal/ejecutable. En ese caso, mi propia solución es la siguiente:

Primero lo primero: la arquitectura de archivo de programa será así (asumiendo que su programa principal es main.jar y presentar sus principales propiedades es main.properties):

./ - the root of your program 
|__ main.jar 
|__ main.properties 

Con esta arquitectura, puede modificar cualquier propiedad en el archivo main.properties usando cualquier editor de texto antes o mientras su main.jar se esté ejecutando (dependiendo del estado actual del programa) ya que solo está basado en texto archivo. Por ejemplo, el archivo puede contener main.properties:

app.version=1.0.0.0 
app.name=Hello 

Por lo tanto, cuando se ejecuta el programa principal de su carpeta raíz/base, normalmente se corre así:

java -jar ./main.jar 

o, enseguida:

java -jar main.jar 

en su main.jar, es necesario crear unos métodos de utilidad para todos los bienes que se encuentren en el archivo de main.properties; Digamos que la propiedad app.version tendrá getAppVersion() método de la siguiente manera:

/** 
* Gets the app.version property value from 
* the ./main.properties file of the base folder 
* 
* @return app.version string 
* @throws IOException 
*/ 
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; 
} 

En cualquier parte del programa principal que necesita el valor app.version, llamamos a su método de la siguiente manera:

String version = null; 
try{ 
    version = getAppVersion(); 
} 
catch (IOException ioe){ 
    ioe.printStackTrace(); 
} 
+7

Esta solución funciona. Gracias por entender el requisito exacto y el código detallado. Comprobé que el archivo de propiedades no está dentro del archivo jar pero aún así podría acceder al archivo desde el mismo director y donde está el archivo jar De esta forma, no se requiere un código absoluto de ruta dura. Tanto el archivo de jar como el de propiedad ahora se pueden copiar en cualquier directorio y ejecutarse de forma independiente. – SoulMan

+1

El archivo no se encontrará si ejecuta el comando desde afuera para ex: {{java -jar build/main.jar}}. ¿Tienes alguna solución para eso, @eee? – Darian

+0

@Darian No hay nada que arreglar aquí; Solo funciona según lo diseñado, donde el archivo jar y el de propiedades deben estar en la misma carpeta raíz '. /' (El mismo nivel de directorio) que lo que he descrito en la arquitectura de organización de archivos. (según el requisito establecido por el póster original) – ecle

0

Siempre hay un problema al acceder a los archivos en su directorio de archivos desde un archivo jar. Proporcionar el classpath en un archivo jar es muy limitado. En su lugar, intente utilizar un archivo bat o un archivo sh para iniciar su programa. De esta forma, puede especificar su ruta de clases de todas formas, haciendo referencia a cualquier carpeta en cualquier lugar del sistema.

También puedes ver mi respuesta a esta pregunta:

making .exe file for java project containing sqlite

27

lo hice por Otra manera.

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(); 
    } 
  1. obtener la ruta de archivo Jar.
  2. Obtiene la carpeta principal de ese archivo.
  3. Use esa ruta en InputStreamPath con su nombre de archivo de propiedades.
+0

Tuve que soltar la parte getParentFile(), así que en su lugar utilicé: String propertiesPath = jarPath.getAbsolutePath(); pero todo depende de dónde se encuentre el archivo – MobileMon

+2

Simplemente reemplace "jarPath.getParentFile(). getAbsolutePath();" a "jarPath.getParent()". Funciona como un amuleto entonces. – StackAddict

+0

Mismo es el problema en mi caso, pero tengo el proyecto base de primavera. ¿Cómo decir a la primavera que el archivo está al lado del archivo jar? alguna idea – Mubasher

0

Tengo un caso similar: quiero que mi archivo *.jar acceda a un archivo en un directorio al lado de dicho archivo *.jar.Consulte también THIS ANSWER.

Mi estructura de archivos es:

./ - the root of your program 
|__ *.jar 
|__ dir-next-to-jar/some.txt 

soy capaz de cargar un archivo (por ejemplo, some.txt) a un InputStream dentro del archivo *.jar con lo siguiente:

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()); 
    } 

Luego hacer lo lo harás con el stream

Cuestiones relacionadas