I have a Spring Java 1.8 project exported in a .jar. When I want to run this Java .jar application, I'd like to give a file into the argument which .xml config file should the program use in the relative folder. I tried so many ways, but none of them works.
For example:
sampleJavaPorgram.jar config1.xml
(config1.xml and sampleJavaProgram.jar is in the same directory)
shoud load config1.xml like that:
ApplicationContext context = new ClassPathXmlApplicationContext("config1.xml");
Maybe use Command-Line Argument, to get name of this XML file and then pass it to AppContext.
Or you might use System properties
Related
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.
Iam using spring boot org.springframework.boot.loader.JarLauncher to run my self executable spring boot app jar.
Now, I have my self executable jar packed like this (For brevity Iam just adding the files only that are needed to show the problem):
Main.jar
---META-INF
---lib
---a.jar
---com
---comp
---Abc.class
---folder1
---1.txt
---2.txt
---b.jar
and so on.
In my Abc.class Iam trying to load the resource 1.txt which is working fine when I run it in eclipse; but the story starts when I run using command line as self executable jar. I was not able to read that resource and ends up with null pointer error.
After reading few threads, I learnt that my IDEs does some magic on Class Loaders and so it was working fine, which will not be the case when I run it as executable jar
This is how I was Loading the files and the all the possible options I have tried to no luck.
Option 1:
Abc.class.getResourceAsStream("\folder1\1.txt")
Option 2:
Abc.class.getClassLoader().getResourceAsStream("folder1\1.txt")
Option 3: Reading thread, I have tried considered the current thread class loader context as below too, But to no luck again
Thread.currentThread().getContextClassLoader().getResourceAsStream("folder1\1.txt")
Can any one advise. How should I write my code to be able to read my resource that is in the jar and by the class that is in the same jar ?
PS: Spring boot is not adding class-path entry to MANIFEST.MF and if I have to do something around that, how do I do that ? In-fact I tried -cp when running my jar setting it to current directory, but that have not worked either
In Spring, the best way to access a Resource is via Resource APIs. For a Classpath resource what you should use a ClassPathResource and it would look something like this:
Resource resource = new ClassPathResource("/my/resource.json", this.getClass());
After obtaining a Resource you can either get a File reference via getFile() or get an InputStream straight off by calling getInputStream().
Spring provides quite a few different implementations of the Resource interface, take a look at the list of known implementations in the docs
Use Spring's class ClassPathResource to load file from classpath.
For example you can read file into String like this from classpath:
String fileContent = FileUtils.readFileToString(
new ClassPathResource("folder1" + File.separator + "1.txt").getFile());
It doesn't matter what kind of build tool or project structure you are using as long as that file is on classpath.
I have a Mule CE application that is using a Java component to transform a CSV file to XML. My Java class needs to access a flatpack XML file called map.xml - I have placed this in src/main/resources. My Java class is in src/main/java. I'm currently accessing the map.xml file in my Java class as follows:
fr = new FileReader("src/main/resources/map.xml");
This works fine in Mule Studio, but when I try and run this application in Mule Standalone, I get the following error:
java.io.FileNotFoundException: src/main/resources/map.xml (No such file or directory)
Is there a way I can make this file path mutual so that it will work in both Studio and Standalone? I have also tried simply fr = new FileReader("map.xml"); and this fails in Studio.
UPDATE
Through a combination of the answer from #Learner, and some info in this post, I've managed to find a solution to this problem. I've updated my Java class to the following and this has worked in both Studio and Standalone:
fr = new FileReader(MyClassName.class.getResource("/map.xml").getPath());
UPDATE
How to retieve mule-app.properties file? If same then will it work onCloudHub as well.
There are couple of ways to do this:
You may read resource as stream like this, files under src/main/resources are in your classpath
InputStream is = this.getClass().getResourceAsStream("map.xml");
The other recommended way is to create your transformer as a spring bean and inject external map.xml file dependency through spring.
Generally when you place in path in src/main/resources it comes under classpath ... In Standalone also it should get it from there ... if not, then could you place it in standalone conf folder where all properties files are kept and have a try
I have a Spring 3.0 MVC project that uses a JAR file from a different project as a dependency. This JAR file has an "auth.properties" file in it's resource and has a string in it like this.
Ex: packages.redirectUrls.gotoUrl = 'http://myUrl.com';
Now, I am referring to this string in JAR File in my controller using:
#Value("${packages.redirectUrls.gotoUrl}")
I also have a local "auth.properties" file that consists of the same string with a different value in it.
Ex: packages.redirectUrls.gotoUrl = 'http://newUrl.com';
However, my Java code is not able to read this new configuration and always loads from the JAR File. Is there a way to override the JAR file setting with this new setting?
Thanks,
I am using tomcat server for my java application(Servlet,jsp).In my servlet page calling one java class function.Actually the java file is written separately and i will call the function written inside it.With in the function, i have to read one config(user defined) file for some purpose.so, i am using File class for that.
But, here i have to give relative path of the config file(user defined).Because, now i am running this application in local windows server.But my live server is based on Linux.So, the file path is changed in linux.
File f1=new File("D:\tomcat\webapp\myapp\WEB-INF\src\point_config.txt"); -- windows
File f1=new File("D:\ravi\tomcat\webapp\myapp\WEB-INF\src\point_config.txt"); -- linux
So, i have to give relative path of the file that is common to both windows and linux machine.
Is there a way to do this?
Please guide me to get out of this issue?
Place your config file under your webapp WEB-INF/classes folder and read like this in code
InputStream is=
YourClassName.class.getResourceAsStream("point_config.txt");
The path of the config file leads into the WEB-INF folder
tomcat\webapp\myapp\WEB-INF\src\point_config.txt
Anything inside WEB-INF is protected and cannot be user-defined once the web application has launched. If you meant to read from a user-defined configuration file from the file system, please use an API like the common configuration API.
If you want to insist on keeping the file inside the WEB-INF folder, use the Class.getResourceAsStream() method to obtain the configuration instead. That would not make the configuration user-defined though.