How do i pass constant values from tomcat to war file(i.e. based upon spring-boot )? - spring-boot

After lot of online search & tried lot of experiments. finally i
didn't get any of the link which can full-fill my requirement, so
finally I choose this platform.
Note : I am using Spring-Boot Maven Project & Tomcat 7.0.62 version & JDK 7.
First of all I was using Embedded Tomcat & produce .Jar and i was passing extra dynamic parameter to .jar using command line argument.
Now, scenario has been changed. My .Jar file will be converts to .war file also we have excluded Embedded Tomcat i.e. not embedded Tomcat.
Now i want to pass same list of command-line argument to my Spring-Boot project's .war file from outside. something like from tomcat.
any help appreciate.

You have a few options in a servlet container/application server:
Use system properties
Use init parameters
Use JNDI
They'll all be available via Spring's Environment so will work pretty much as it you'd passed them in via the command line.

Related

url after spring maven deployment

I have a basic question about deployment but I can't seem to find an answer on google...
I am working on a jakarta project and it's the first time I do the deployment.
Since I am using Spring-boot maven, I know there is an embedded tomcat that will launch with the jar.
My issue is, I don't know what url to use to check my project is working...
Before, I used the address http://localhost:9091/contextPath/endpoint, but now, I only get a whiteScreen...
So my question is, what url should I use ? Also, is there something else to do after packaging ?
Thank you for your answers.
EDIT:
Alright, so I tried actuator but that didn't help me...
With /actuator/mappings, I could see that my endpoints are correctly configured but when I use the executable jar, http://localhost:9091/contextPath/endpoint odes not work while it does if I compile with my IDE...
I don't know what url to connect to just to see the index... I'm using a very basic spring framework (boot and mvc) and my IDE is intellij community if this helps anyone
EDIT 2:
I tried to deploy the app on a local Tomcat9 to see if something would change but the connexion is reinitialized everytime I try to deploy a war using the manager, and there was no trace of error in the logs.
I tried using ./mvnw and it did work, endpoint and all, but it implies working with IDE environment
I tried using java (openjdk 13) and it compiled, but i couldn"t acces my own endpoint. I could still access the actuator endpoints so i don't know what to make of it.
Should the url be different depending on whether we are using IDE environment or just the jar?
EDIT 3:
Ok, I think have a lead but I have no idea how to resolve this:
when I began the web part of the application, I created a WEB-INF folder where I put all my jsp. My js and css files were in the resources/static folder. I tried once to put the jsp in the resources folder but it didn't work so I didn't push too hard.
Now, when I unzip the jar, i find my css and js files, but not my jsp.
When I unzip my war file, I have everything, but when I try to deploy it on a separate tomcat server, the connexion resets and I don't know why because nothing is written in the logs.
The issue then becomes:
Right now, I have
└──src
└──main
├──java
├──resources
| ├──static
| | ├──css
| | └──js
| └──template
└──webapp
└──WEB-INF
└──classes
└──jsp
What is the standard tree in intellij with jsp ?
By default Spring Boot apps are on port 8080.
Can you try http://localhost:8080?
Port can be changed in application.properties (or application.yml, application-profile.properties etc.) via server.port property (e.g. server.port=8888).
Ok, I managed to make it work.
I'm going to describe here everything of note that I encountered.
First, when I called my app to the usual url, there was no response (whiteLabel).
I added test logs and i found that I indeed called m controller.
I unzipped the jar and war i produced and came to the conclusion that the issue was architectural. I couldn't use jar, I had to use the war file.
I tried to deploy on a local tomcat server using the manager, but it always resetted the connection, so I took the manual approach - copy pasting the war file in the webapp directory.
Finally, the web pages were accessible in the browser.
Thank you for all the tips given during my research!
`http://endpoint:{PORT}/actuator/health` or `http://endpoint:{PORT}/actuator/status`
it should help but it must require spring-boot-actuator as a dependency in your pom/gradle file.

How to specify Log4j2 configuration file in spring boot application

I am using log4j2 in my spring boot application. This works in all respects re: excluding slf4j, including log4j2, etc.
But when the application deploys I need to customize the file for each target host. I have created an ansible role that does this. Ultimately I end up with a log4j2.xml file deployed in another directory e.g. /prod/produsrX/data/log4j2.xml.
I am using the spring-boot-maven-plugin "repackage" goal to generate an executable jar file. It doesn't seem like that should matter but it is a data point in the problem.
This was supposed to be the easiest part of the project. Always before I have just been able to set -Dlog4j.configurationFile - advice which is echoed on about 3,000 web pages and DOES NOT WORK in Spring Boot 2.1.3.
The most useful info I've found is this question. It talks about using -Dlogging.config because logging must be initialized before other properties are read. Unfortunately that didn't help either.
I did find one example that suggested specifying the above directory in a -classpath parameter to java. But that didn't help either.
Does anyone know how to get a spring boot application to read the log4j2.xml file?
The property actually has to be put into the application context (e.g. application.yml). Using a -D property does not work!
logging:
config: /prod/produsrX/data/log4j2.xml #fully qualified name to your log4j.xml

spring boot application properties based on spring profiles

Hi I want my spring boot web project to be deployed both on development and production environment and it should be run on specific profile based setting.
I googled on how to do that, and first of all that I have searched is defining application-{profile name}.properties properly in the src/main/resources classpath.
Now the problem is how to set profiles.
Since I am working on tomcat 8 in linux, there should be some configuration but I don't know how to do that.
and I am also curious that when my project is packaged as war file, java -jar {filename} -Dspring.active.profile=blahblah will not be work, but I think there is an alternative way.
plus, is there an way to set profile on tomcat 8 in Windows 10 ?
Thanks you
First:
I will recommend get rid of dedicated tomcat server and use embedded tomcat, jetty etc. Build your web apps as jar files and just run them. (of course if you don't have any limitations)
Second: You can do this either system property or env variable.
If you go with system property (order is important)
java -Dspring.profiles.active=blahblah -jar {filename}
If you go with env variable you need specify
SPRING_PROFILES_ACTIVE=blahblah

How to identify the batch application name in Liberty on the batchManager submit command invocation

I'm new to Liberty and am trying out the Batch (352) functionality. I can't find this as having been asked, either through search engines or stackoverflow, so I'm apparently missing something blatantly obvious...
I've created a simple test application in Liberty 8.5.5.9. It has the structure:
testbatchEAR
testbatchWAR
testbatchBatch
The EAR has been added to the server through the usual Add/Remove menu pick.
I'm now trying to submit the job from the command line using:
batchManager submit --batchManager=localhost:9443 --user=<> --password=<> --trustSslCertificates --jobXMLName=TestProcessor.xml --applicationName=testbatch
And I get back a message (truncated):
Error: Server returned HTTP response code: 500 for URL: https://localhost:9443/ibm/api/batch/jobinstances: [Error 500: com.ibm.ws.jbatch.rest.bridge.BatchContainerAppNotFoundException: Failed to load the application context for application testbatch#testbatch.war. Verify the application is installed.
I've tried testbatch, testbatchEAR, testbatchWAR, but from the "testbatch#testbatch.war" part of the message, it looks like it just uses the same name for both EAR and WAR, which I don't think is possible, is it?
What part of this am I missing? It must be right in front of my face, but every example or solution I find is using a naked WAR, which I can't do. Is there anywhere in liberty where I can find the application name? Should I be defining the names somewhere (server.xml?)?
Thanks in advance!
* Edit: Additional Information *
If I run it from the Eclipse Run Configurations > Java EE Batch Job section, it does run it, and doing a batchManager listJobs shows the application name as testbatchEAR#testbatchWAR.war.
So I guess the real question I have, is how can I put this name into the --applicationName option of batchManager.bat? It takes and makes #.war out of it. I've tried putting the full name from listJobs, but it won't allow a '#' character...
Specify both --applicationName and --moduleName in an EAR application
(As you discovered), in a case in which the batch application is packaged within a WAR within an EAR you will typically have to specify both --applicationName and --moduleName, e.g.:
batchManager submit --batchManager=localhost:9443 ... --applicationName=testbatch --moduleName=testbatchWAR.war ...
Specify just --applicationName in a WAR application
You may have seen examples though in which only the --applicationName is needed, e.g. here.
This syntax works in the case that the batch application is packaged as a WAR (but not a WAR within an EAR).
The "utility project" name here is not relevant, and there is no EJB so there is no --componentName relevant either.
The doc does mention this here in the section:
POST /ibm/api/batch/jobinstances
...
The applicationName identifies the batch application. It is required unless moduleName is specified, in which case the applicationName is derived from the moduleName by trimming off the .war or .jar suffix of the moduleName. For example, if you provide no applicationName and moduleName=SimpleBatchJob.war, then applicationName defaults to SimpleBatchJob.
The moduleName identifies the module within the batch application that contains the job artifacts, such as the JSL. The job is submitted under the module's component context. The moduleName is required unless applicationName is specified, in which case the moduleName is derived from the applicationName by appending .war to the applicationName. For example, if you provide applicationName=SimpleBatchJob and no moduleName, then moduleName defaults to SimpleBatchJob.war.
But if you're creating both a Web project and an EAR project in a tool like WDT, you're not going to easily be able to give the projects the same names (since they'll collide), so this really only works well in the case that there's not a separate EAR project. When the EAR project exists, you need both parameters.

Spring in production

What is the best practice to make changes in beans.xml file in production environment?
Lets imagine Hello World application with one Interface and 2 Implementations. After creating jar and running JVM how can we change implementation in beans.xml without opening jar and reassembling it afterwards?
Is it any trick that permits having beans.xml outside the jar, but without knowing the full file-system path?
On top of suggestion made by OrangeDog, I would suggest considering leaving the beans.xml inside your deployed application AND using the PropertyOverrideConfigurer mechanism.
Configure an override configurer to point to some fixed path outside of the application, something like /opt/configuration/something/override.properties would be ideal. If you can't use an absolute path, you can always try to play with file:../../.. style of paths. Then you can list only the changed values within the override.properties file.
Don't have the XML in a JAR. Your application should be deployed in at least a WAR, which the app server will probably "explode". The folder WEB-INF/classes will be added to the classpath. You can make changes to the exploded XML here and the app server should detect this and reload the app.
Edit:
If you are using plain Java SE, you can use a system property to pass the location of the XML file. System.getProperty("property") in code and -Dproperty=value on the command line.

Resources