Java 我可以使用类路径来覆盖正在运行的 jar 中的文件吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1708534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I use the classpath to override a file in a jar that is being run?
提问by Guss
I have a JAR file that contains an application as well as configuration files for that application. The application loads configuration files from the classpath (using ClassLoader.getResource()
), and has its dependencies completely satisfied using the configuration files baked into the JAR file.
我有一个 JAR 文件,其中包含一个应用程序以及该应用程序的配置文件。应用程序从类路径加载配置文件(使用ClassLoader.getResource()
),并使用烘焙到 JAR 文件中的配置文件完全满足其依赖关系。
On occasion I want the application to be run with a slightly different configuration (specifically I want to override the JDBC URL to point to a different database) so I create a new configuration file, store it in the correct directory structure (which means in a directory /config
of a classpath entry), and I want to do something like this:
有时我希望应用程序以稍微不同的配置运行(特别是我想覆盖 JDBC URL 以指向不同的数据库)所以我创建一个新的配置文件,将它存储在正确的目录结构中(这意味着在一个/config
类路径条目的目录),我想做这样的事情:
java -cp new-config:. -jar application.jar
But I can't get the classpath to have the new-config
path entry before the application JAR's contents. Is it hard-coded that the JAR's content is always the first thing on the classpath?
但是我无法让类new-config
路径在应用程序 JAR 的内容之前具有路径条目。JAR 的内容始终是类路径上的第一件事是否是硬编码的?
采纳答案by alasdairg
Why not just invoke the application without specifying -jar and instead name the application main class explicitly? This will allow you to put both your new-config and the application.jar on the classpath in the required order:
为什么不直接调用应用程序而不指定 -jar 而是显式命名应用程序主类?这将允许您以所需的顺序将 new-config 和 application.jar 放在类路径上:
e.g. (assuming "new-config" is a directory containing the overridden properties file)
例如(假设“new-config”是一个包含被覆盖的属性文件的目录)
java -cp new-config:application.jar Application.Main.Class
I believe the name of main class can be found in the MANIFEST.MF file inside the jar ....
我相信可以在 jar 内的 MANIFEST.MF 文件中找到主类的名称....
回答by Kelly S. French
It may not be possible using just the CLASSPATH. There are ways to get make the call to ClassLoader.getResource()
use a static path to find the resource. If it is doing that, it is bypassing the CLASSPATH.
仅使用 CLASSPATH 可能无法实现。有多种方法可以调用 ClassLoader.getResource()
使用静态路径来查找资源。如果这样做,则它绕过了 CLASSPATH。
回答by Gerd Klima
The JAR archive specified by the -jar option, overrides all other values.
-jar 选项指定的 JAR 存档覆盖所有其他值。
You would have to generally do it with an outside config file or build your own solution withod ClassLoader.getResource()
.
您通常必须使用外部配置文件来执行此操作,或者使用 od 构建您自己的解决方案ClassLoader.getResource()
。
We use a custom solution to solve this - we load the internal properties like so:
我们使用自定义解决方案来解决这个问题 - 我们像这样加载内部属性:
final Properties p = new Properties();
p.load(DefaultConfiguration.class.getResourceAsStream("config.properties"));
We then load the external file in the same way and overwrite the internal values with the external ones.
然后我们以相同的方式加载外部文件并用外部值覆盖内部值。
For info on how class loading works see:
有关类加载如何工作的信息,请参见:
http://java.sun.com/javase/6/docs/technotes/tools/findingclasses.html
http://java.sun.com/javase/6/docs/technotes/tools/findingclasses.html
回答by Adamski
When you use the -jar option to launch your application:
当您使用 -jar 选项启动应用程序时:
... the JAR file is the source of all user classes, and other user class path settings are ignored.
... JAR 文件是所有用户类的来源,其他用户类路径设置被忽略。
as described here. A workaround would be to specify the classpath in the jar file's manifest to include the additional path (described here).
作为描述在这里。一种解决方法是在 jar 文件的清单中指定类路径以包含附加路径(此处描述)。
However, given that you are only talking about amending configuration you may want to take a different approach that is not reliant on the classpath. For example, I typically configure my applications through Spring using property files to determine the location of databases, etc. My Spring configuration is consistent across test, QA and live environments but I pass a different property file as a command line argument when launching the app.
但是,鉴于您只是在谈论修改配置,您可能希望采用不依赖于类路径的不同方法。例如,我通常通过 Spring 使用属性文件来配置我的应用程序以确定数据库的位置等。我的 Spring 配置在测试、QA 和实时环境中是一致的,但我在启动应用程序时将不同的属性文件作为命令行参数传递.
Spring Configuration Snippet
Spring 配置代码段
<bean id="MyDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
<property name="url" value="jdbc:microsoft:sqlserver://${dbServer}:${dbPort};DatabaseName=${dbName}"/>
<property name="username" value="${dbUserName}"/>
<property name="password" value="${dbPassword}"/>
<property name="suppressClose" value="false"/>
</bean>
Property File Snippet
属性文件片段
dbServer=MyServer
dbPort=1433
dbName=MyDb
dbUserName=Me
dbPassword=foobar