Maven configuration: pass file inside a classpath jar as an argument - java

Several maven plugins need/support passing a java.io.File as a configuration parameter, wherein we specify the relative/absolute location of the file for the plugin to locate and use.
Is there a way I can specify a property file in the plugin configuration where the file has to be found from inside a jar in the classpath? I'm particularly wanting this to know and use with the aspectj-maven-plugin, where I can specify the Xlintfile value to be the custom XlinkDefault.properties file location. The file, in my case, will be found inside a classpath jar.
I use maven-2.2.1 by the way.

No, not in general; there's no magic that will turn something that's not a file on disk into a java.io.File. Many Maven plugins (e.g., maven-checkstyle-plugin's configLocation are designed to allow more flexible input for just these cases:
This parameter is resolved as resource, URL, then file. If successfully resolved, the contents of the configuration is copied into the ${project.build.directory}/checkstyle-configuration.xml file before being passed to Checkstyle as a configuration.
As a workaround, if the plugin cannot be changed, dependency:unpack may be a way to get a classpath resource into a local file (see Maven: extract files from jar).

Related

Access property/environment variables without launching Eclipse?

I want to set the log4j configuration file path/other folder paths that can be used across other class files, without hard-coding the folder path.
Rightnow, I have set the variables as Environment variable. But It can only be modified if I launch Eclipse. How do I set this variable in such away that anyone (doesn't want to launch Eclipse) can modify it, from outside. Also, it will be used in test configurations. So it's better to not hard-code it and have all the file paths etc. easy to refactor.
final static String log4jpath = System.getenv("LOG4J_PATH");
Paraphrasing a comment:
[How to get value from] outside of the Java program such as a separate file, that contains all other filepaths?
That is called a configuration file.
It is often a properties file, similar to a Log4j configuration file, but it can be any types of file, e.g. XML, JSON, YAML, ...
To identify a single such file, you can use:
An environment variable (like you are right now)
A system property (more common)
A specifically named file in the current directory
...
The entries in that file will identify all the values you really want.
For example, Spring, which is a populate Java framework, will look for configuration values in many places. See 24. Externalized Configuration for full detail, but here is a summary of the most common ones:
Command line arguments, e.g. java -jar MyApp.jar --foo=bar
Java System properties, e.g. set using -Dfoo=bar on the command-line
OS environment variables, e.g. SET foo=bar (Windows) or export foo=bar (Linux)
Application properties outside of your packaged jar, i.e. relative to current directory.
Name and location can be overridden on command-line.
config/application.properties
config/application.yaml
application.properties
application.yaml
Soni, If you want to put the log4j configuration file in one place so that everybody can access. Follow the steps.
Create a project with some name and inside src/main/resources folder keep the log4j configuration file.
Create a jar file which must contain this log4j configuration file.
Use this created jar file wherever it is required. Log4j will automatically use the configuration for desired logging. If you want, you can distribute this jar file to anybody who wants to use it.
The above option is if you do not want to change the configuration file.
Now if there is a situation where someone wants to modify the configuration file.
In this case, simply put the configuration in any project classpath, means inside resource folder. As long as log4j jar files are there in the classpath and configuration files. It will log everything.
However, if you want, you can extend the functionality of Log4j by passing configuration as an object. You can refer below the link to access pro grammatically.
https://howtodoinjava.com/log4j/how-to-programmatically-configure-appenders-in-log4j/
I have added all file and folder paths inside the properties file (example config.properties) and then used it inside the testsetup method by InputStream input = new FileInputStream("Path to//config.properties");
Properties prop = new Properties();
prop.load(input);
System.setProperty("log4j2.configurationFile", prop.getProperty("log4j.path"));
this way, all files/folder paths can be modifies from outside and there's no need to set environment variable from inside the project.

Override properties file from jar

I have a properties file in one of the .jar of my maven dependencies. I would like to override the values in my application so I created a file with the same name and the same package, but the values from the jar file are still being used. If I delete the properties file from the jar, the values of the file in my application are used. How can I always use the properties from my application instead of the .jar ?
As long as code takes your property file from class path it depends how your class path configured.
If you externalized your file out of any jar files - Try to put path to directory where your actual file located upfront of any other jar files in your java command -cp parameter.
If you keep your file inside your own jar file, in classpath - your jar file must be before that dependency jar file with default properties file.
Still those are not good solutions (sometime it is hard to control which path JVM will use first).
So, try to find documentation about your dependency jar - it may have a property to point from where and which properties file to use.
You can use Maven Resource Plugin and parametrize your configuration file so you can pass the parameters as arguments through command line
Use the properties resource in the jar as template, initial file for the properties file you will use:
Path propertiesFile = Paths.get(System.getProperty("user.home"),
".myapp/config.properties");
Files.createDirectories(propertiesFile.getParent());
if (!Files.exists(propertiesFile)) {
Files.copy(getResourceAsStrem("/config.properties"), propertiesFile);
}
Properties props = new Properties();
props.load(new FileInputStream(propertiesFile.toString());
How about this ?
rename the properties file with overridden values,
like this _override.properties (if the actual file is
called original.properties.
Now, in your code, read a system property, called 'toOverrideProps', if true, to load the overridden properties file
when running your program, you can set this property using the -Dprop=value method
This way, you have a choice on startup, to use the actual properties file or the overridden one, without conflict.

Can't add single XML file to Tomcat's classpath

I want to add a file to the classpath of all applications running on my Tomcat 7 server.
When adding
${catalina.base}/conf/myfile.xml
to common.loader in catalina.properties it's not working.
But adding just
${catalina.base}/conf
does the trick.
However, I just want to add a specific file, not the entire directory. The comments in catalina.properties state the following:
[…] Prefixes should be used to define what is the repository type. […]
[…] Examples: "foo/bar.jar": Add bar.jar as a class repository […]
Unfortunately I haven't found out with which prefix I should mark my file. Do you know more about this?
When you add something to the classpath, it it always either an whole directory; or a whole JAR file (which you may consider as an packed directory). You may never have a single file entry in your classpath.
Proposed solution: Either live with the conf/ directory; or pack your myfile.xml in a JAR file (even if it only contains a single file).

Classpath variable in java

I'm reading a few files in my application and referring to them as new File("src/main/resource/filename") and it works. But when I package the jar with the Maven assembly plugin and run java - jar I get an error, naturally:
Error occured: src\main\resources\UPDATE.txt (The system cannot find the path specified)
Because there is no src/main/resources in the jar, how can I refer to src/main/resources as some kind of classpath variable, so that the application works both in standalone java and in an assembled jar?
You will need to load the file using the Class.getResourceAsStream() method
E.g.
InputStream str = getClass().getResourceAsStream("/UPDATE.txt");
Or if you are in a static method, then specify the class explicitly
InputStream str = MyApp.class.getResourceAsStream("/UPDATE.txt");
EDIT:
With a StreamSource, just pass the input stream into the stream source, e.g.
new StreamSource(getClass().getResourceAsStream("/UPDATE.txt"));
But watch out, getResourceAsStream returns null if the resource doesn't exist, so you might want to explicitly check for that and throw an exception.
The src/main/resources is a development time convention followed by maven projects to place artifacts other than source code. Once the jar has been build they are added to the classpath. So in your e.g. scenario the UPDATE.TXT is at the root of the classpath.
So you should be referring to the resources from the classpath and not from the file-system. http://mindprod.com/jgloss/getresourceasstream.html

How to change the path of displaytag.properties?

Currently i have placed the Displaytag.properties in 'src' directory, and it is working fine. Is it posssible to have this file on some different location like src/comp/bre/sub/config ?
From the docs for the DisplayTag library:
For the whole web application, create
a custom properties file named
"displaytag.properties" and place it
in the application classpath.
Displaytag will use the locale of the
request object to determine the locale
of the property file to use; if the
key required does not exist in the
specified file, the key will be loaded
from a more general property file.
So in your case make sure your build scripts (or IDE) copy your displaytag.properties file from src/comp/bre/sub/config the onto the classpath.
In an IDE this is normally as simple as specifying that a particular directory contains source code. In ANT just make sure the displaytag.properties file ends up in your /WEB-INF/classes.
Find the code which loads this properties file and add the new path. You can also place it in a folder yourProject/src/resources/ and add it to the classpath. Therefore, your properties file will be placed in the binary folder once the code will be compiled.

Categories

Resources