How to modify a properties file in spring boot jar - java

I am writing a Spring Boot Application.
This application talks to a Main Frame through MessageQueues
So inorder to talk to that MainFrame we are provided with a java jar(which has the code that talks to MessageQueues ). lets call it proxy jar.
We have to use the operations written from the above mentioned proxy jar .
We dont write any code to read/write to MessageQueues (IBM MessageQueues) in our application, this is done by the proxy jar and its dependent runtime jar.
So here comes the problem, this Proxy jar is coded in such a way that it looks for a file called 'commcfg.properties' in the classpath (expects the name to be exactly same). Actually the Proxy jar uses another dependent jar (lets call runtime jar)which reads the queue details from commcfg.properties and reads/writes from Message Queues.
commcfg.properties have the values of MessageQueue and Host and port of those Queues . In short Queue details.
So the trouble is these MessageQueue details will be different in different environments. I need to use the commcfg.properties according to environment
So far my trials to solve this.
Lets say I have two environments .
So I will have two different set of values of commcfg.properties
I have created files as follows
commcfg.DEV.properties
commcfg.PROD.properties so that they will be in classpath
Next I have written code such that it will pick up the particular property
file depending on Environment and rename it to commcfg.properties(as the
Proxy jar and its helper dependent Runtime jar need the exact name to be
commcfg.properties).
In my local workspace I could do this .
But when deployed (we use docker) that gets packaged into spring boot jar.
So my hack is not working as we cannot rename files with in jars.
Another thought I had:
Before I call my functionality code , I will put the commcfg.properties in
class path (project/src/main/resources)
I will read it and modify the values as needed per environment.
The values I will have them in application.properties.
But again I doubt that with in jar I cannot modify the file.
Hoping I am clear
Kindly help me out..

In spring boot, You can register your properties file with a Java annotation #PropertySource
#SpringBootApplication
#PropertySource("classpath:commcfg.properties")
public class ApplicationConfig
{
public static void main(String args[])
{
SpringApplication.run(ApplicationConfig.class);
}
}
and let the commcfg.properties file contain the DEV environment details
messageQueue.name=myMessageQueue
messageQueue.host=host
messageQueue.port=4040
Now build your jar file and you get yourjar.jar
Now run it in DEV environment with default values
java -jar yourjar.jar
run it in QA environment with overriding the default values in your config file
java -jar --messageQueue.name=diffrenthost --messageQueue.host=diffrenthost --messsageQueue.port=diffrentport yourjar.jar
This way you can override your default values. I hope this helps

you can put the properties files on the same path of spring-boot jar, the config items can override the properties in the jar.

Related

Use single profile-specific property file from multiple application.properties files

I have a few spring-boot microservices and I want to use a single profile-specific property file for all the microservices. profile-specific property file should be outside of the jars.
example:
The application-common-profile.properties file and jar files are inside the same folder
java -jar Microservice-1.jar --spring.config.location=classpath:/application.properties --spring.profiles.active=common-profile
java -jar Microservice-2.jar --spring.config.location=classpath:/application.properties --spring.profiles.active=common-profile
the above commands won't take the common-profile properties. please help to achieve this. Thanks.
IMPORTANT DETAILS
This jar file doesn't contain 'application-common-profile.properties' file. this file resides outside the jar but in the same folder. if I put my 'application.properties' file inside the same foder then it is working(retrieving the properties) with the below command.
java -jar Microservice-1.jar --spring.config.location=C:/folderpath/ --spring.profiles.active=common-profile
I can place other microservices 'application.properties' files in same folder with different names(ex: application-microservice-2.properties). and also the profile property files with different names.(ex: application-microservice-2-common.properties ) It's okay having different application.properties files. but need to have one common profile property file.
FIXED
I added common profile property file(application-common.properties) and jars in same folder and run below commands simply and it is working. I think adding unnecessary arguments was the problem.
java -jar Microservice-1.jar --spring.profiles.active=common
java -jar Microservice-2.jar --spring.profiles.active=common
If your application.properties file is bundled in your jar, then simply adding the profile-specific property file to your working directory will allow it to be picked up. However, when you set spring.config.location you're overriding the path that Spring will look up these properties from, you should drop this, it's not necessary. Spring will look in your working directory for the properties files by default if they're not bundled in the jar.
Personally, I would avoid trying to maintain the property files in the environments in favor of environment variables.
Bundle your jar with the top-level application.properties included in it, and for the variables that are different given the environment, set environment variables for them.
e.g. if you want to override spring.datasource.driver-class-name, set the environment variable SPRING_DATASOURCE_DRIVER_CLASS_NAME. I think you'll find this approach is far more flexible.

Java class not loading from javaclassloader service in IIB

I have an application build in IIB v10 where i am referencing a java routine from esql. I have created the java class as an independent resource, then exported it as a JAR file and placed it in a folder under C://lib. There was an existing configuration service for java class loader which also pick yet another jar file from C://lib. I then amended the existing configuration service for Java Class loader with the new jar name and its path. Also, did a restart of the broker and inspected via mqsireportbroker command and webconsole to confirm the new jar has been updated in the configuration service. Now when i deploy the BAR file to the server, I am getting the below error.
BIP3202E: (com.xxxx.soa.xx.xxx.createMD5Hash, 1.12) : An error occurred when trying to resolve the Java class or method 'com.xxxx.gen.createMD5.createMD5Hash' which is referred to by the routine 'createMD5Hash'.
Further messages are generated that explain the error in more detail.
Correct the syntax of your Java expression in node 'com.xxxx.soa.xx.xxx.createMD5Hash', around line and column '1.12', then redeploy the message flow.
BIP2943E: The Java Method 'com.xxxx.gen.createMD5.createMD5Hash' could not be found as its containing class could not be found in the deployed bar file or in the 'workpath/shared-classes/' directory.
The specified Java Method 'com.xxxx.gen.createMD5.createMD5Hash' belongs to a class that could not be found in the deployed bar file or the 'workpath/shared-classes/' directory. Ensure that the fully qualified name of the method is correct and that its containing class or jar file is in the deployed bar file or in the 'workpath/shared-classes/' directory.
Examine and correct the SQL program.
When I put the jar file under workpath/shared-classes directorey, its working. But I want the jar file to take from the shared class librarry which is C://lib. What am I missing in this case?
All you need to do it to put your jar in the shared-classes folder.
You can find all the information about it in the IBM documentation really easily, but here is an example on Unix :
/var/mqsi/config/MY_BROKER/shared-classes
You can either put the .jar there, and it will be loaded for each execution group (also called integration servers).
If you know you only need this for a specific execution group, then you can copy it there :
/var/mqsi/config/MY_BROKER/MY_EG/shared-classes
And I would highly recommand you to use the second option, otherwise you might have performance issues if you do this with a lot of libraries
There are only a few paths where the .jar files are loaded from.
See for more information: https://www.ibm.com/support/knowledgecenter/en/SSMKHH_9.0.0/com.ibm.etools.mft.doc/bk58210_.htm
JAR files are loaded in the following precedence order:
JAR files placed in the integration server shared-classes directory allow only a single defined integration server to access them. Files placed in here are loaded first.
JAR files placed in the broker shared-classes directory allow only a single defined broker to access them. Files placed in here are loaded after any files placed in the integration server shared-classes directory.
JAR files placed in the top level shared-classes directory are made available to all brokers and all integration servers. Files placed in here are loaded after any files placed in the broker shared-classes directory.
I found it on windows here C:\ProgramData\IBM\MQSI\config*\shared-classes
using this command mqsireportbroker <my_broker_name>

How to JBOSS deploy ESAPI property files directory configurtion

We'd like to configure ESAPI property files directory, in JBOSS WildFly
(What usually done by VM argument: -Dorg.owasp.esapi.resources="/path/to/.esapi")
but prefer to do so in OTHER way, to suppurt diffrent property configuration for diffrent projects
does someone know how to do so?
Thaks!
There's really only two methods for loading these files, neither of them care about the application server you use. The first method, as you suggested is to supply the path via JVM properties.
The second method is via the classpath. I've never worked in JBOSS, but in Weblogic there's a config menu where you can place files on the classpath directly. In your case, it sounds like you want a different properties file for multiple applications? A JVM property or a similar classpath edit to weblogic would be the only choices.
The final classpath method, which I'm only including to be complete, is to compile your own copy of the library with your properties files in src/main/resources. Or--really hacky--crack open the jar file and dump them in by hand. The benefit of the "compile yourself" approach is that you'll have all the unpublished bugfixes, so if another CWE gets assigned to it you don't have to wait for the official release.

Play framework 1.2.4 war environemnt specific configuration file

Is there a way to include environment specific properties or configuration file while building war.
QA
entity.url=http://qa.test..
prod
entity.url=http://prod...
I need to make around 5 to 6 REST calls. Url is different for each environment. Hence is there any way to configure environment specific conf file?
thanks in advance
The Play Framework has the concept of 'ids' that can be used for different modes see here:
http://www.playframework.org/documentation/1.2.4/ids
This allows you to do:
%qa.entity.url=http://qa.test..
%prod.entity.url=http://qa.test..
The one thing that might not be clear by their documentation is how to set this in a war. When running as a .war file, the play ID is set to 'war' by default. This can be changed in the web.xml of the .war file. You can do that or you can specify the ID when you create the war:
play war -o PATH --%prod
Not that I am aware of (and reading the python source for building the war does not indicate this is available). The war file simply builds up your Play application, as is. If you want to have a different configuration, then this may simply require the loading of it from an external resource (a property file that lives outside of the WAR, that you ship with your WAR file).
Alternatively, you could modify the python script that builds the WAR file to custom add additional properties to your file. Look in the directory framework/pym/commands/ and look at the war.py to read the source for the python war command.

How to configure logging when running a JAR?

I am new to Java logging API and need some help with this problem:
While creating the application, my config file was stored in the project root folder, so I used -Djava.util.logging.config.file=logging.properties switch to run the program.
But then I exported the executable JAR.
How to configure the logging now? It doesn't work, when I specify the path to config file with the -D switch.
You can't specify JVM arguments into the MANIFEST.MF file so you have to specify the logging properties at the command line or with a shortcut :
java -Djava.util.logging.config.file=logging.properties -jar yourjar.jar
Otherwise you could package a properties file(logging.properties in your case) in the JAR, read that at
startup and put those settings into the system properties.
The javadoc says:
In addition, the LogManager uses two optional system properties that
allow more control over reading the initial configuration:
"java.util.logging.config.class"
"java.util.logging.config.file"
These two properties may be set via the Preferences API, or as command
line property definitions to the "java" command, or as system property
definitions passed to JNI_CreateJavaVM.
If the "java.util.logging.config.class" property is set, then the
property value is treated as a class name. The given class will be
loaded, an object will be instantiated, and that object's constructor
is responsible for reading in the initial configuration. (That object
may use other system properties to control its configuration.) The
alternate configuration class can use readConfiguration(InputStream)
to define properties in the LogManager.
So, either use the java.util.logging.config.file system property, and store the config file out of the jar file (which is probably a good idea if you want to be able to customize the logging properties in order to debug or analyze some weird behavior), or store the config file wherever you want (in the jar file, for example), and use the java.util.logging.config.class system property to load and instantiate a class that will read the file in the jar file (Using Class.getResourceAsStream()).
I know it's little late to answer this question but I ran into this issue few days back with the runnable jar and I solved it like this:
java -Djava.util.logging.config.file=logging.properties -cp test.jar com.sample.test.Main
where test.jar is the name of your jar and com.sample.test.Main is the fully qualified name of your main class.

Categories