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

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.

Related

Can you replace a Spring Boot jar while the application is running?

In our Linux environment applications are restarted periodically (the reasons aren't important here). It would be convenient for us to deploy new versions of an application by copying the application Spring Boot jar on top of the existing (old) jar thereby overwriting it and then simply wait for the application to restart (that is, the JVM running the application to restart).
However, this seems to not work. We get different kinds of errors - sometimes the app just hangs, sometimes we get a ClassNotFoundException. It's as if Spring Boot (or something inside Spring Boot) reopens the jar and expects it to be the same one it was when the application was originally started.
We had a look through Spring's common application properties, but didn't see anything appropriate. Is there a way to make this work? When we were using WAR files we configured the servlet container to unpack the WAR file and run from the unpacked version. Can we do something similar with Spring Boot?
First of all the errors you are experiencing can come from multiple sources. Usually replacing the file from a process is not a big problem as the whole file is loaded into memory before execution. Java is a little bit different, because the actual process that is running is the JVM and it only loads the jar file from disk. The JVM loads classes only on demand, this means if there was any class that was not loaded before it will try to load it and most likely fail, if the jar file is different. In the case of spring boot there are also other resources (such as HTML files) inside the jar file that are dynamically loaded.
You mentioned you are using a linux environment. If you can just replace your startup with a script you can just copy the jar and start it from the copied location:
#!/bin/bash
JAR_NAME="spring-boot.jar"
NEW_JAR_NAME=".$JAR_NAME" # Use an appropriate name here
cp $JAR_NAME $NEW_JAR_NAME
java -jar $NEW_JAR_NAME
rm $NEW_JAR_NAME
Now every time you start the application a copy is being made and started from there. You can replace the original jar and on the next restart the new application will load.
You coud also use rsync instead of cp to avoid copying the same jar twice, if the application is restarted multiple times without changing the jar.
It would be convenient for us to deploy new versions of an application
by copying the Spring Boot jar on top of the existing (old) jar and
then simply wait for the application to restart
Why would you do such a thing to yourself? You are trying solve a usecase that's against best practices, sound like asking for trouble just to avoid an app restart. When you are doing a deployment, you need to make sure the deployment went through, otherwise how will you troubleshoot if something goes wrong in your application, you will have one more variable in hand when you troubleshoot, i,e the uncertainty of current version of the code.
If you are having downtime while deploying (I am assuming thats why you want to limit the restarts), why don't you bring up another instance with the newer version of code and once its healthy shutdown the old one

How do i pass constant values from tomcat to war file(i.e. based upon 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.

Separating client and server side deployments JavaEE & Website dev

I need to deploy 2 packages to Wildfly:
1. EAR file - containing all server side (JavaEE) code.
2. WAR file - containing website code (HTML,JS,CSS...).
In order for the website path to be something like localhost:8080/somename/index.html, I need to specify <finalName>somename</finalName> in Maven. On the other hand, the EAR file contains the RESTful stuff, and in order for the REST to be under the somename context root I added the appropriate tag to maven-ear-plugin.
Now... I guess Wildfly doesn't like 2 things to be registered under same name, so I can't deploy the website.
What is the proper way to approach this problem? Combine the two projects under the same name and deliver only one package?? maybe change the context root of the EAR since it's "the RESTful voodoo stuff" that is not really important?
I would really want to register the two under the same context root but leave both projects separated.
You can't register two different WAR's under the same context. Since you want to leave the business logic separate from the UI it's probably best to register the WAR with your REST services under a different context.

Externalizing static content from a WAR and serve both on jetty

In my project I use Maven to package a web application to a WAR which is later deployed to Jetty using a custom Maven plugin on CentOS. The custom plugin is used by every project that deployes to a production environment. There is now a requirement that all static content (like web site text, properties) is packed outside of the WAR so that it can be changed in production without requiring a new release cycle. I am unsure how to achieve this externalization.
The Jetty server has the directory structure described in Jetty quick start guide. Currently, the web application already offers some .properties files which can be altered externally, and these reside in the resources/ directory. These files are moved here by the custom Maven plugin. The WAR resides in the webapp/ folder. One option for my problem is to use <packagingExcludes> of maven-war-plugin to not include e.g. *.xhtml and *.properties in the WAR. Later, I can use the custom Maven plugin to move excluded files to resources/ directory. But, I have a feeling this is not the correct way to externalize static content... Shouldn't xhtml files live in webapp/ folder while the only the properties file live in resources/ folder?
I have also researched the option of deploying the WAR as exploded, but I am unsure of the implications of such. Clearly, the changes in the exploded WAR files will be overwritten in the next deploy, but the idea is to do static changes both in development and production. Also, I am not sure how to achieve WAR "explosion", is it something that Jetty does for your WAR if configured in jetty.xml or do I have to extract the WAR before deploying?
Lastly, how do people serve static content in Jetty which can be altered in production? Do both the WAR and static files live side by side
The Jetty resources folder should not be used for application files. A J2EE web application (war) should be self-contained -- and in Jetty, reside only on the /webapps folder -- and its only binding to the container (Jetty servlet engine) is via the web.xml deployment descriptor.
Since property files may be read from the classpath and the Jetty resources folder is part of the system classpath, a property file there could be read by the web application class loader. Note that there are other ways to read property files as well and the Jetty resources folder should not be used for application properties. Also, the application may not be portable as other application servers have different forms of webapp classloader isolation.
If the below architecture approach does not work for you, then your only approach would be to expand (explode the war) in the /webapps folder and hope for the best when files are edited.
Tackling this from a different angle,
- if your web application depends on .properties and .xhtml files in order to function properly, then these files are probably not 'content'. The fact that there is a business process that requires them to to be updated ad hoc does not make them content.
- 'content' is something like text, images, and videos that is added, edited and removed by an administrative user. The application does not depend on it for correct execution, it merely reads and passes it on the browser.
Suggestions:
I would suggest that you deploy your application every time there is a change to the .xhtml or .properties files change. If the editors of these files are power business users, you might think of a git push-pull tool for them and a continuous build hook, so that when they make changes and push them to the git repository, the application gets tagged with a newer version and gets built and deployed. If there is a problem (tag not closed in xhtml), then it would be easy to roll back to the last tag.
Alternately, if the changes are minor (such as text descriptions), then modify the application to read them from an arbitrary external file (outside the webapp) -- a location that is provided to the webapp on startup. You can then package a 'default' version of the file in the webapp, but the code would attempt to look in the specified external location first.
I discovered that you can add HTML tags to properties and later use <h:outputFormat> to fetch these properties with parameters. Also, you can do pretty neat stuff with property files as described in MessageFormat API.
My solution was to keep the .xhtml files inside the WAR, but use simple HTML snippets properties from the default resource bundle which is based on a .properties file. These properties were included in the .xhtml using <h:outputFormat>and <h:outputText>. This allows the user to add simple styling like bold and underline to the snippets.
The properties file are copied to the Jetty resource folder using the custom Maven plugin, so I have kept the .properties files in the WAR. For some reason the Jetty resource folder has precedence over the packed .properties files, so this works out fine. Also, as Akber pointed out, I will have the default versions of the properties available if for some reason the WAR was moved to some other application server where the resource folder is not available.
Of course, with this approach the code can break if malformed HTML is placed inside the snippet properties, as pointed out by Akber, but it works for our application as it is very small. I may never have done this if this was a much larger application, but then I might have gone for a database based solution for adding static text (like Joomla/Drupal/Wordpress).

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