Using ActiveJDBC (version 1.4.13), I can't find a way to override the database.properties bundled with the application (the one from src/main/resources/database.properties ending inside the jar).
Is there a way to override it with a local file (in the same vein as with application.properties in Spring Boot)?
Please, see documentation here: http://javalite.io/database_connection_management#using-system-property
Basically, provide the location of your database.properties file as a system property:
java com.company.project.Main -cp myprogram.jar -Denv.connections.file=/path/to/file/database.properties
However, if it does not work for you, it is because of this bug that was fixed in Feb 2018:
https://github.com/javalite/activejdbc/issues/681
so, if this configuration does not work, keep in mind that the file is searched on the classpath. This means that if you put your file somewhere on the file system and list the directory of this file first on your classpath, your file will be found first as opposed to the one packaged into the Jar file.
So, if your file is: /opt/project/dir1/database.properties, you can start your process:
java -classpath /opt/project/dir1/:$CLASSPATH com.yourcompany.Main
then the file /opt/project/dir1/database.properties will be loaded first.
Related
With this setup (from Eclipse using Windows10)
I was able to correctly start my SpringBoot application. This one worked too (same directory pattern):
Now I'm packaging my project as JAR and I want to use an external properties file. I had an teste32.yml file beside my JAR at the same directory (also tried to use it inside /config directory, as show here, but it didn't work either)
I want to dynamically use a properties file beside my JAR file everytime. Doesn't matter at which directory they are, I wanted to dynamically point to a properties file always at the same directory as the JAR is. I want to say to my client: "take this JAR and this file, put them wherever you want and run this command X and everything will be alright". I'm trying to discover command X but before I add some dynamic path, I'm trying with absolutes paths. I'm using this:
java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target\
I manually copied teste32 inside target\ to test this. But this didn't work. This didn't work either (only spring.config.location variants):
-Dspring.config.location=file:C:\workspace\myProject\target\
-Dspring.config.location=classpath:/
-Dspring.config.location=file:C:/workspace/myProject/target/
I also tried with no spring.config.location, only name
So my questions are:
What does classpath: and file: mean? Until now I got the 2 correct setups by pure luck and I would like to understand when to use them.
When I have my project package as a JAR, what classpath becomes?
Finally, which combination is necessary to dynamically use a properties always at the same directory as the JAR?
UPDATE
Using --debug at the correct example got me this line at the very begging (Spring banner was still visible):
2018-09-25 15:45:14.480 DEBUG 11360 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:src/main/resources/xirulei/teste32.yml' (file:src/main/resources/xirulei/teste32.yml)
But after moving myJar.jar and teste32.yml to a specific directory and running java -jar myJar.jar -Dspring.config.name=teste32 --debug (without spring.config.location, since teste32 is at the same directory as JAR), I simply didn't get any ConfigFileApplicationListener debug line.
a) java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target
Did you check content of target dir? I'm pretty sure your cfg file is placed to target\classes\xirulei and it is why Spring cannot find it in target
b) When you place teste32.yml in the same directory as jar file then Spring must be able to find it (given this directory is working directory) without -Dspring.config.location (but you still need to provide -Dspring.config.name=teste32)
c) When you use -jar and do not provide additional class paths then classpath: points to the root of packages inside jar. Spring cannot find your file at classpath:/ because your file is at classpath:/xirulei/
Well, after all it was a simple mistake. As documentation says and as already pointed here, it should be
java -jar myproject.jar --spring.config.name=myproject
and not
java - jar myproject.jar -Dspring.config.name=myproject
As stated on question, only when using Eclipse -D(JVM argument) is necessary. When using bash/cmd, just --(program argument) is the correct option:
from the manual:
24.3Â Application property files SpringApplication will load properties from application.properties files in the following locations and add
them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
It mentions current directory twice but this really doesn't mean anything:
I tried putting it in the root of my project (i.e. above src in the folder that matches the output of java.io.File( "." ).getCanonicalPath() and System.getProperty("user.dir");), and I tried putting it with the war files (i.e. in build\libs)
But the only place to put it that actually works is the default location (src\main\resources).
So what does "current directory" even mean and where do the files really go?
I need to find the correct external location for the files so I don't have to build database credentials into the app.
The guides say that putting application.properties in current directory will work and I found the exact current directory to put it in but it still doesn't work, which I can verify by the output of: System.out.println(System.getProperty("spring.datasource.url")); which is null It does output the correct value only with an embedded properties file.
According to ConfigFileApplicationListener:
// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS =
"classpath:/,classpath:/config/,file:./,file:./config/";
file:./ resolve to the working directory where you start the java process.
I agree with Stephane Nicoll's argument that we generally don't need this for development and test but needed for production where properties file is generally externalized and the one present in source code is not used. This is what works for me ,
java -jar myjar.jar --spring.config.location=file:D:\\RunRC\\application.properties
Directory - D:\\RunRC - mentioned in above command is sample from my machine.
I keep using properties file of source code i.e. from \src\main\resources\ in development and test but in production , I comment out entries and if I am starting my jar or war from D:\\RunRC then I provide Current Directory as shown in above java command and keep properties file there.
Just doing - #PropertySource({ "application.properties"}) or #PropertySource({ "file:application.properties"}) doesn't pick it up from the directory where jar or war is kept.
For database credentials, I would suggest to use OS specific environment variables and use syntax similar to - #PropertySource({"file:${CONF_DIR}database.properties" }) where CONF_DIR is existing environment variable pointing to that directory.
Hope it helps !!
I understand that the current directory is the root directory of your project. However, you can change this with -Dspring.config.location=your/config/dir/.
Have a look at this post enter link description here
If you search for "current directory java", you'll end up here with this question. The intention is that if you put an application.properties in the same directory as the application, it will be picked up by default.
You will not use that feature in development or for test as you shouldn't rely on that feature. But when running your app in production, it might be handy to put environment-specific settings in a configuration file that sits next to the application itself.
Current directory refers to where we execute our jar. Creating an executable jar via Spring Boot maven plugin and placing application.properties just beside the jar file will work. An example :here
My application is packaged into a jar file and is run with the regular "java -jar ..." command.
I have a properties file "myApp.properties" in the directory: /opt/myuser/resources
I want to add the /opt/myuser/resources directory to the classpath. I believe this is advantageous because when the properties files are on the classpath, I can access the properties files in my source code without specifying the full path to the properties files (/opt/myuser/resources/myApp.properties). This way I can keep a properties file with environment-specific properties separate from my application.
I've tried to set the classpath using instructions from Oracle (http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html under "Using the JDK tools' -classpath option") like this:
java -cp .:/opt/myuser/resources -jar myApp.jar
but I get an error that the properties file myApp.properties (referenced in the source code) cannot be opened:
Caused by: java.io.FileNotFoundException: class path resource [myApp.properties] cannot be opened because it does not exist
Am I going about this the wrong way? Should I edit the classpath in another way?
Hopefully this will help someone else.
I've used as program arguments for spring boot
--spring.config.location=file:/opt/myuser/resources/myApp.properties
and then it will use that file.
pass this parameter in VM options/environment variables
-Dspring.config.location=/deployments/tomcat/instance-conf/myApp.properties
use gerResource solutions to load file on your Properties Object:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");
I wrote a program that works on my laptop perfectly, but I really want it to work on a server that I have. Using NetBeans, I've clean and built the project. I copied the contents of the folder dist on my server but I cannot seem to get to work by using command
java -jar nameOfFile.jar
I get the error
java.lang.NoClassDefFoundError: org/....
I have been doing some reading and from what I gather is that I need to pretty much specify where the libraries that I've used are located. Well they are located in a subfolder called lib.
Question:
So what would I need to do in order to be able to run my jar?
CLASSPATH is an environment variable that helps us to educate the Java Virtual Machine from where it will start searching for .class files.
We should store the root of the package hierarchies in the CLASSPATH environment variables.
In case of adding or using jar libraries in our project, we should put the location of the jar file in the CLASSPATH environment variable.
Example: If we are using jdbc mysql jar file in our java project, We have to update the location of the mysql jar file in the CLASSPATH environment variable. if our mysql.jar is in c:\driver\mysql.jar then
We can set the classpath through DOS in Windows
set CLASSPATH=%CLASSPATH%;c:\driver\mysql.jar
In Linux we can do
export CLASSPATH=$CLASSPATH:[path of the jar]
Hope it helps!
Try that:
java -classpath "$CLASSPATH:nameOfFile.jar:lib/*" path.to.your.MainClass
What this does is setting the classpath to the value of $CLASSPATH, plus nameOfFile.jar, plus all the .jar files in lib/.
Classpath
A compiler(e.g. javac) creates from .java - .class files and JVM uses these .class files.
classpath - local codebase[About] - points on the root of source. classpath + import_path = full path
For example for MacOS
//full path
/Users/Application.jar/my/package/MainClass
//classpath
/Users/Application.jar
//import_path
my.package.MainClass
Android classpath
ANDROID_HOME/platforms/android-<version>/android.jar
//e.g
/Users/alex/Library/Android/sdk/platforms/android-23/android.jar
When you use a META-INF/MANIFEST.MF file to specify the Main-Class dependencies must be specified in the manifest too.
The -jar switch ignores all other classpath information - see the tools docs for more.
You need to set class path using
The below works in bash .
This is temporary
set CLASSPATH=$CLASSPATH=[put the path here for lib]
If you want it permanent then you can add above lines in ~/.bashrc file
export CLASSPATH=$CLASSPATH:[put the path here for lib]:.
You have 2 questions, one is the "title question" and another is the "foot note question" after elaborating your problem.
Read this documentation bellow to get a better understanding of CLASSPATH.
https://docs.oracle.com/javase/tutorial/essential/environment/index.html
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html
This is fast and straight forward for what you need.
For your first question, this will do:
The documentation recommends us to set a classpath for every application we are running at the moment using (use in the command-line):
java -classpath C:\yourDirectoryPath myApp
For your second question, look this exercise in the java documentation. It seems to be the same problem:
https://docs.oracle.com/javase/tutorial/essential/environment/QandE/answers.html
Answers to Questions and Exercises: The Platform Environment
Question 1.A programmer installs a new library contained in a .jar file. In order to access the library from his code, he sets the CLASSPATH environment variable to point to the new .jar file. Now he finds that he gets an error message when he tries to launch simple applications:
java Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Hello
In this case, the Hello class is compiled into a .class file in the current directory — yet the java command can't seem to find it. What's going wrong?
Answer 1. A class is only found if it appears in the class path. By default, the class path consists of the current directory. If the CLASSPATH environment variable is set, and doesn't include the current directory, the launcher can no longer find classes in the current directory. The solution is to change the CLASSPATH variable to include the current directory. For example, if the CLASSPATH value is c:\java\newLibrary.jar (Windows) or /home/me/newLibrary.jar (UNIX or Linux) it needs to be changed to .;c:\java\newLibrary.jar or .:/home/me/newLibrary.jar."
I am using one third party jar in my code. In the jar file , in one of the classes, when I opened the class using de-compiler, the code below is written:
java.net.URL fileURL = ClassLoader.getSystemResource("SOAPConfig.xml");
Now I am using this in my webapplication, where should I place this SOAPConfig.xml so that it will find the fileURL.
Note: I have tried putting this XML in WEB-INF/classes folder. But it is not working. Your help will be appreciated.
In Addition: In the explaination you have given, It is telling me not to use this code snippet inside the third party jar in this way...What is the exact usage of this statement
ClassLoader.getSystemResource will load the resource from the system classloader, which uses the classpath of the application as started from the command line. Any classloaders created by the application at runtime (i.e. the one that looks in WEB-INF/classes) are not on the system classpath.
You need to
Look through the script that starts your server, find out which directories are on the classpath there, and put your SOAPConfig.xml in one of those. If necessary, change the classpath in the script to look in a separate directory that's just used for your config file.
Track down the person who used ClassLoader.getSystemResource in the library, kick them squarely in the nuts, and tell them never to do that again.