Spring profile loading without being specified - java

I have a Maven/Spring boot project that I'm seeing some odd behavior in. To summarize, a spring profile is attempting to load, but that profile doesn't exist and isn't specified ANYWHERE in my code. It seems as if the profile name is being picked up from a different Java command line property though, which is why it is confusing me.
Essentially my command line looks something like this:
Java -DEnvironmentID=qa01 -jar myapp.jar com.something.package.Loader LOAD
From what I understand from Spring documentation's command line documentation is that I would need to call java with the -Dspring.profiles.active=profileName argument in order to invoke a profile. So while I'm NOT doing this, "qa01" is being picked as a profile and my application tries to load "application-qa01.properties"
During my testing, I've also noticed that small modifications to the "-DEnvironmentID" argument will prevent this from being picked up as a profile (ex. "qa10", "qa0", "a01", "qa100", etc...)
I'm stumped at this point and can't determine why it would be picked as a profile argument by Spring.

Just in case this could help someone in the future:
The problem was rooted in a dependency of my project. The dependency happened to use the same command line argument as my own to build out a path to the environment specific properties file packaged within the jar. The dependency project just happened to build out the properties file name/path just like a Spring profile, so it ended up not actually being related to profiles after all. When the dependency jar failed to provide the properties file, Spring continued to look for the file in my project, eventually throwing the error.

Related

Read updated configurations from application.properties without repackaging the uber jar

Is there a way to read the updated changes in application.properties without repackaging the jar in Quarkus? I could not find anything related in the official documentation at https://quarkus.io/guides/config-reference. So I am assuming that the uber jar has the application properties built in. So is there a way to override those configs while running the jar?
Edit: What I mean by overriding is: Is there a way to specify the path of the config file that the jar reads while running the jar. Something similar to java -jar app.jar -DConfig='/path/to/application.properties'.
In Quarkus some of the configurations are fixed at build time, (the once in the documentation with the lock). Others are not, this ones you can change them at runtime using several methods, for example, using environmental variables or properties in the launch commands.
Check this links for more information:
https://quarkus.io/guides/config#build-time-configuration
https://quarkus.io/guides/config-reference#configuration-sources
As you can see in the configuration-source section, quarkus will firstly search in system properties and other sources rather than in the application properties file, there is one possibility for you to change the value of your properties.

How to check that a Class is on Build Path when using Spring dependency injection

I am using Spring for dependency injection. The context is configured by XML files. I am using Eclipse. Is there any way in Eclipse, how to check if the classes, used in the xml files when creating beans, are on the Build Path?
Example:
<bean id="myBean" class="com.example.MyClass" />
How can I check that MyClass is on the Build Path in Eclipse?
I think you are referring to ClassPath, as classes are present in ClassPath(even jars are the part of classpath). Moreover I am not really sure about the question, if the classes are not there in your classpath, spring will give exception while trying to resolve those dependencies. However if you want to know the location where this class is defined that too in eclipse, just press control and click on the class. It should tell you from where eclipse is picking up this class file.
I hope that my understanding of the question is right and hence the answer is pretty close to what you were looking for.
Your project won't deploy correctly - check the logs.
But your ide if its any good, will alert you before then.
BUT even better you should have unit tests that reveal the error.
As mentioned by #chrylis in a comment, the STS bean config editor will issue a warning or error about referenced classes that don't exist. Note that sometimes a bean config file is not opened in the Spring Config editor automatically. If the editor doesn't have a tab at the bottom called "Namespaces" then it's not the Spring-specific editor. In that case, right-clcik on the file and choose Open with > Spring Config Editor.
Once you're in the Spring Config editor, a quick way to check is to put the cursor in a class name then press F3 which should take you to the class definition if it's on the project build path.

Eclipse: Get the project name as a VM argument?

Consider a configuration class which needs to parse a different config file for each Eclipse project.
For instance, If Configuration class is called from Project1, it should parse special/path/fileX, and if it is being called from Project2, it should parse special/path/fileY.
I've tried using Eclipse's {project_name}, but surprisingly it is being parsed to the project being highlighted by the cursor, not the parent project of the current class.
Any ideas how can I distinguish one project from another in Eclipse Runtime, preferably using JVM arguments?
This is a workaround to your described problem, but I guess it's a better solution as it's independent from Eclipse and will easily work in production too.
Simply load the same file from the classpath, regardless which Project you're starting this from:
/my/file/from/classpath.txt
But put this file only in Project1 / Project2, such that the various files mutually exclude themselves according to your set-up:
/Project1/src/my/file/from/classpath.txt
/Project2/src/my/file/from/classpath.txt
Where src are Java source folders. Now you can still use your JVM parameter to override this, or to provide a default if the above is missing.
I think the easiest way would be using eclipse's run configurations. Simply create as many configurations as you want, supply all the JVM args you want, and use them to launch. This will also be very close to what you're going to do in production mode
or you can go to your Eclipse' Installed JRE's and have the configuration set as JVMArgs just the way you would have in prod.
If required, you can have diff copy of JREs per env.
Also if running from the IDE, you can get the
System.getProperty("user.dir")
which should be the root of the project.
that system property can be used to track the callee. Better still, set the Installed JRE's JVM Args to be something like this
-Dtheflaginprod=${project_loc}
project_loc = absolute path of the the project (/usr/projects/project1)
project_path = project name relative to the workspace (/project1)

Avoiding hardcoding of Property File path specification

I'm having a small problem decoupling the path specification for properties files that my JAVA program uses , from the implementation itself.
The program may be deployed at multiple locations with different directory structures and I don't want the path specification to be hard coded into the Program code.
Here is the situation as it exists now.
I have one folder server/
Inside which there are 2 packages core/ & support/ (both of which have many subpackages underneath)
What I had done earlier was that , wherever the path for a properties file needed to be specified , I just gave a relative path i.e. properties/
In this scenario, the properties file needs to be wherever you're launching the program from. This worked during testing , when i was manually starting the program up using
"java ". and i would put the properties folder wherever I was starting the program from.
But in a real scenario, this program will be autostarted by a script (ksh) which is executed at scheduled intervals by a job.
In this case , giving the relative path doesn't work. I tried putting the properties files in the folder where the scripts are located , but that doesn't work either.
Right now , I am having to manually specify the path for each environment recompile the code and deploy a separate copy for each environment.
Is there any way to remove this coupling and just have one location for the properties file regardless of where it needs to be deployed?
use a System.Properties entry to specify the path, then on command line add it via
java -DmyProp=somepath -cp yourclasspath YourClass
In your app, you can retrieve it with System.getProperty("myProp"), just be sure to add proper testing and handle the Property Not Found scenario.
Another practice is to leave props in a jar and then load 'em with the LoadResource, in this way you just need to deploy different config jars in each deployment, but I think that the System.setProperty way is the fastest.
Generally some clients may not prefer to use -D= while starting your application. In fact you should also provide a .sh/.bat script file along with your jar file so that client can just double click on the script to run your application.
In this script you can have variable declared which you can ask the client to be configure accordingly. Client can just open the script file in text editor and type in the path of the configuration file.
Other way to use this script file would be to do following :
1) Check if YOUR_APP_NAME_CONFIG variable is set in system environment. If yes then go to step 3 or got to step 2
2) Ask the user on command line for the location of configuration file. Check if the location is correct. If correct then set the environment variable YOUR_APP_NAME_CONFIG with value of location of configuration file.
3)Start your application
Having a script file for your application gives you lots of liberty to do many stuff around automating the environment configuration for your application.
In your application get the config file path by System.getProperty("YOUR_APP_NAME_CONFIG").
This all may look like lot of pain but think from client perspective. Its cake walk for client that he just double click a script to start your application and for the first launch of application the script asks for some inputs if needed and then your application is good to go :)
What I did was pass another classpath parameter with the jar invocation..
java -cp classpath1;folder-where-propertiesfile-located Application.jar
and in the application use getClass().getClassLoader().getResourcesAsStream("properties-file");
This will automatically fetch the properties file form the appropriate classpath folder..
With this setup, I could change the properties file inside the folder and use the same jar file without re-archiving the jar..

Reload Class When Dependent Resource Changes in Spring

You know how Eclipse reloads classes automatically running in Tomcat when resource files they depend on such as spring context files are updated so that you don't have to re-start Tomcat? How do I make a class dependent on a resource file so that Eclipse re-publishes it when the resource file changes? Eclipse would re-publish Spring classes when their dependent resource files are updated, but would not re-publish mine.
I'm not sure if it's Spring that's doing this for you. Are you developing in an IDE like Eclipse or Netbeans? What might be happening is as you make code changes your IDE is 'publishing' (i.e. re-deploying) your app code, so the app re-initializes every time the IDE publishes it, giving the illusion that Spring is reloading context files as they change.
This is useful with a small app but get's very annoying the larger your app gets.
If you're looking for this behavior for development, take a look at JRebel:
http://www.zeroturnaround.com/jrebel/
You say that you want the class to be republished ? Do you mean that you want the contents of the bean in the application context to be updated ? If that's the case, then what you can do is the following :
1) Write a file system monitor to monitor the resource(s) for changes. There's an example on google code
2) Have that file system monitor fire a custom Spring ApplicationEvent whenever the file / resource changes, providing that event the information for the resource, if necessary. ie the file name, the previous modified time, the last modified time, etc.
3) Have the bean you want to be updated implement ApplicationEventListener and reload the resource when it catches your file system monitor event.
A simple but working workaround can be to add an ant builder to your project. Steps to take:
read the article
here
http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.user/gettingStarted/qs-93_project_builder.htm
create a simple ant file, that
contain a target, which touches
(simply changes the date of
modification) the dependent classes,
but nothing else (if you need help in it, let me know). Eclipse will provide you variables inside the script. You can print them easily with task. You will see the list in console.
right click on the project, and
press properties
open "builders" tab in properties
add your ant script as a builder to
the project
restrict the set of resources this
ant builder is called for. This can
be done in "build options" tab in ant
builder options. This way your
project will be fast, and the ant
script will only run for the changes
of the property file
set the set of resources (classes depending on properties) to refresh after running the ant script in "Refresh" tab
Set your ant script target to be called for "Auto build" in "target" tab. Others like after and before clean and manual build should be empty
You may redirect log of the ant script to file if you want. Otherwise it will open console view.
move your builder to be the first in the list of builders, since it must run before java builder
This is a workaround, and should work. It will have no bad side effect, since the content of java file will not change, and it will not affect the version control system, as well as the whole thing is workspace independent, if the ant script is in your project.

Categories

Resources