I have a simple Spring application with reading configuration values from a properties file. The file is configured to be on classpath by default (#PropertySource("classpath:thefile.properties") annotation on a configuration class). I want to be able to optionally use some another properties file that I can (but don't have to) specify in command line on the program startup. I.e., I eventually want to run something like this:
java -jar application.jar --path "some/location/thefile.properties"
Now values from the specified file should be used.
I have already tried using SpringBoot and the spring.config.location option both before and after the jar:
java -jar "-Dspring.config.location=file:some/location/thefile.properties" application.jar
keeps using values from the file on classpath
java -jar application.jar "--spring.config.location=file:some/location/thefile.properties"
complains about unrecognized option
My main class looks like this:
#SpringBootApplication
public class MainClass {
public static void main(String[] args) {
SpringApplication.run(MainClass.class, args);
// Application code triggered here...
}
}
I don't need to use SpringBoot, I just want to set the properties file location somehow. Any idea? And is this possible at all?
Do something like this on your property class :
#Configuration
#PropertySource(value = "file:${myapp.external.config}")
**Command** java -jar -Dmyapp.external.config="C:\yourPath\abc.properties" xyz.jar
If you have multiple external properties files, example below
#Configuration
#PropertySource(value = {"file:${app1.config}", "file:${app2.config}"})
**Command** java -jar -Dapp1.config="C:\yourPath\abc1.properties"
-Dapp2.config="C:\yourPath\abc2.properties" xyz.jar
This worked for me on Windows : "C:\Program Files\Java\jdk-15.0.1\bin\java" -jar C:\Users\your.name\YourApp.jar --spring.config.location="C:/Users/your.name/yourAppProps.properties".
Related
I have a simple spring boot application that returns value of a system env variable
application.properties
my-var=${SYSTEM_ENV_VAR}
where SYSTEM_ENV_VAR is a system variable defined in /etc/environment
DemoApp.java
#SpringBootApplication
#RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Value("${my-var}")
String env;
#GetMapping(path = "/")
public String get() {
return "This: " + env;
}
}
I follow the process of creating an executable jar with mvn clean package
Now, when I execute the jar as /home/ubuntu/sample-app/target/demo-0.0.1-SNAPSHOT.jar, I get the correct value of my system environment variable
I created a service
/etc/systemd/system/demoapp.service
[Unit]
Description=desc
After=syslog.target
[Service]
EnvironmentFile=-/etc/environment
User=root
ExecStart=/home/ubuntu/sample-app/target/demo-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
I execute the service as sudo systemctl start demoapp.service.
When I check the status sudo systemctl status demoapp.service, I see an error trace
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder
'SYSTEM_ENV_VAR' in value "${SYSTEM_ENV_VAR}"
But I know that /etc/environment is loading since I can see other entries in the log which show the loading of all my system envs
Can anyone help me with this? Thanks.
Value that you are using for ${my-var} should not be ${SYSTEM_ENV_VAR} instead should be the actual path to the system variable.
So your application.properties should have
my-var=path/to/system/variable
and not
my-var=${SYSTEM_ENV_VAR}
Ok. So this is what I ended up doing.
I noticed that removing the export keyword in my /etc/environment resulted in the value of SYSTEM_ENV_VAR being interpreted and displayed.
But now apache started complaining since it could not find the value for SYSTEM_ENV_VAR. Therefore, I split the declaration into 2 parts. So the file looks like:
/etc/environment
export SYSTEM_ENV_VAR
SYSTEM_ENV_VAR=the-value
This way, apache and spring boot both are happy.
I have a java Spring boot project which uses a MySQL database. I have the following application.properties file to specify the MySQL url, user and password:
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_PASSWORD}
Using this property file, I can run the application from Eclipse if I edit the run configurations and set the values of DB_HOST, DB_PORT, DB_NAME, MYSQL_USER and MYSQL_PASSWORD in the Environment tab and run it.. everything works fine.
But now I want to run it on the server, by generating a JAR and passing these values from command line to the Jar during run time. So, I created a Jar file like this:
/gradlew clean build bootJar -DDB_HOST=mock -DDB_PORT=mock -DDB_NAME=mock \
-Dmysql_user=mock \
-Dmysql_password=mock
this successfully generates the executable Jar file.. then I try to run the generated jar file like this:
java -jar build/libs/MyApplication.jar -Ddb_host=localhost \
-Ddb_port=3306 \
-Ddb_name=my_db \
-Dmysql_user=root \
-Dmysql_password=root
but it gives the following error:
...
Failed to parse the host:port pair '${DB_HOST}:${DB_PORT}'
...
java.lang.NumberFormatException: For input string: "${DB_PORT}"
...
Which means that it is not actually replacing the values during runtime.
How do I fix this?
Edit: I also tried to open up the jar using archive utility and saw the application.properties file.. it contains the following line:
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
which means that these values should have been updated during runtime. but it isn't
I was eventually able to get this to work by adding a DatasourceConfig class and setting the values programatically.
I removed all the spring.datasource.* values from my application.property file and then created a new class:
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class DatasourceConfig {
#Bean
#Primary
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(System.getProperty("MYSQL_URL"));
dataSource.setUsername(System.getProperty("MYSQL_USER"));
dataSource.setPassword(System.getProperty("MYSQL_PASSWORD"));
return dataSource;
}
}
This allows you to configure the datasource, username and password externally as VM arguments at runtime.
The values MYSQL_URL,MYSQL_USER,MYSQL_PASSWORD are passed onto the gradle command while building like this:
./gradlew clean build bootJar -DMYSQL_URL=mock -DMYSQL_USER=mock -DMYSQL_PASSWORD=mock
, and similarly to the java command while running the jar like this:
java -jar build/libs/MyApplication.jar -DMYSQL_URL=jdbc:mysql://localhost:3306/my_db -DMYSQL_USER=root -DMYSQL_PASSWORD=root
You just need to expose those Fields as Environment Variables before running the jar.
For Linux:
$ export DB_HOST=localhost
$ export DB_PORT=3306
$ export DB_NAME=my_db
$ export MYSQL_USER=root
$ export MYSQL_PASSWORD=root
$ java -jar build/libs/MyApplication.jar
i'm working on spring boot project and all works fine , now i want to build and run the app.
in the application.properties file i set the property server.port = 8090
after building the project using maven i run the following command
java -jar jarfilename.jar but it says the port 8080 is already in use.
i try these commands:
java -jar -Dport=8090 jarfilename.jar
and
java -jar jarfilename.jar --port=8090
but also i got the same message the port 8080 is already in use.
I'm wondering why it takes the port number 8080 and ignore the port number 8090 that i set in the application.properties file.
Note : (I'm using tomcat embedded server) and when i check the folder target/classes.. application.properties i didn't find the property server.port=8090.
can anyone explain to me what' happen exacly?
thanks in advance.
Is the application.properties located at the right location?
Description from Spring.io:
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
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
Use java -jar -Dserver.port=8090 jarfilename.jar to set the port from command line.
Hint, from Spring.io: If you want to use the short term -Dport=8090, you can use server.port=${port:8080} in your application property file.
I encountered the same problem, in my case, I didn't pass the args to SpringApplication.
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class);
}
should be
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
when you create spring boot application using 'spring initializer' select jar file
I know its an old post, but I might know the answer(maybe it will help others): There is a hierarchy with the configuration settings.
The applicaton.properties file is at the bottom(OS env. variables, Java System properties etc. are all above), on the other hand, terminal parameters are at the top.
So when the server initialized, it used the port from a property setting, that is higher in the hierarchy ladder.
I created the following class located in the MainJPrint.java file
import com.XXXXX.pdfPrint.PDFPrint;
public class MainJPrint
{
public static void main(String[] args)
{
//System.out.println("Hello World!");
print(".....");
}
public static String print (final String url)
{
Object rc = AccessController.doPrivileged(new java.security.PrivilegedAction()
{
public Object run()
{
...
}
}
}
}
In the same folder I have a jar archive jPrint.jar
I compile the class using the following command
>javac -classpath jPrint.jar MainJPrint.java
When I'm trying to execute resulted class file, I get this error:
>java MainJPrint
java.lang.NoClassDefFoundError: com/XXXXX/pdfPrint/PDFPrint
If I uncomment the Hello World line and comment the next line, the program runs fine.
I'm using j2sdk1.4.2 installed at C:\j2sdk1.4.2.
I do also have installed other java versions (at C:\Program Files\Java: jre 1.6.0_01, jre 1.6.0_02, j2re1.4.2, jre6, jre7, jdk1.7.0_03)
The PATH variable contains the C:\j2sdk1.4.2\bin path, however I think the java.exe is loaded from the upper version, but it shouldn't matter and I can call it like
>C:\j2sdk1.4.2\bin\java.exe MainJPrint
jPrint.jar is a third party archive and I need to create an applet which exposes a method so I can call it with javascript. I'm not a java developer, I'm having some little troubles and I'm really on an end here.
I tried other options like:
>java MainJPrint -cp .
>java MainJPrint -cp jPrint.jar
So how can I execute that class file which uses a class located in a separate archive?
To execute a class that depends on external JARs, you need to specify all elements of the classpath on the command line.
If you don't specify a classpath, Java automatically uses . (the current directory), which is why, if MainJPrint didn't depend on jPrint.jar, your invocation java MainJPrint would have worked.
But when you specify -cp jPrint.jar, Java does NOT automatically add the current directory to the classpath, which means that it then cannot find MainJPrint. You need to specify both. On Mac/*nix, the following invocation should work:
java -cp jPrint.jar:. MainJPrint
Or on Windows:
java -cp jPrint.jar;. MainJPrint
I have a java class "Test.java" which contains certain code.
public class Test {
public static void main(String[] args) throws Exception {
testMount();
}
public static void testMount() throws Exception {
System.out.println(System.getProperty("os.name"));
//Windows
String volumeToMount = "\\\\?\\Volume{****-****-******-********}\\";
String mountPoint = "C:\\temp\\";
mountFileSystem("", "", volumeToMount, mountPoint); //This carries out the operation
}
}
I have already compiled the code in Linux Operating System. I want to run the compiled code through a batch script ( .bat file). How do i do that? What is the syntax for that? If i have to add some external jars, where and how do I insert them in the syntax within the .bat file?
here is an example of bat file for executing a java code from the jar with external jars:
#echo off
if "X%JAVA_HOME%" == "X" goto setjavahome
goto setup
:setjavahome
rem #### MODIFY ##########
set JAVA_HOME=c:\program files\javasoft\jre\1.2
rem #######################
:setup
set JNDI_LIB=lib\ldap.jar;lib\jndi.jar;lib\providerutil.jar;lib\ldapbp.jar
set JSSE_LIB=lib\jsse.jar;lib\jnet.jar;lib\jcert.jar
set COMMON=.;%JNDI_LIB%;%JSSE_LIB%
set EXEC=browser.jar lbe.ui.BrowserApp
set CMD="%JAVA_HOME%\bin\java" -cp %COMMON%;%EXEC%
echo %CMD%
%CMD%
.bat is for Windows; try to compile your Java codes in Windows to EXE (with your external libraries, as suggested by galchen), and add your EXE name along with relative / absolute path to the batch file.
For example, the output EXE is named as test.exe, the batch file should contain:
START C:\PATH\TO\YOUR\EXE\test.exe
Advantage of compiling to EXE is mainly for performance.