Wildfly pass parameters to deployments - java

I have one WAR file with application.
What I need to do is to deploy this WAR twice in one application server (Wildfly) under two different names - deployment1.war and deployment2.war. So far, this is no problem.
The application in the WAR is reading configuration from configuration file and the path to the configuration is currently hardcoded in the application. I need to change this so the deployment1.war is reading deployment1.conf file and deployment2.war is reading deployment2.conf file.
I don't want to keep two different source codes (differing only in the location of the properties file).
So my question is - is there any possibility to pass specific parameter to deployment instead of whole server? Or any other way how to parametrize concrete deployment?
Thanks

You can use overlay to override a file in your deployment thus using 2 different web.xml each pointing to the proper configuration file. https://docs.wildfly.org/20/Admin_Guide.html#Deployment_Overlays

Related

Spring based SOA using multiple WAR on Tomcat, what is the best way to enfore URL mapping?

I am in the process of migrating an old model 1 java based website, to use an under development restful-api (with the long term goal of providing a PaaS and any other buzzwords I can find).
I want to use multiple different WAR files for different modules of functionality. I know how to do this
www.myLegacy.com/myWarFile/myFirstMethod
www.myLegacy.com/myWarFile/mySecondMethod
www.myLegacy.com/mySecondWarFile/ThirdMethod (in different war file, and consequently diff url)
However I want to be able to deploy multiple war files to the same url like :
www.myLegacy.com/myRest/myFirstMethod
www.myLegacy.com/myRest/mySecondMethod
www.myLegacy.com/myRest/ThirdMethod (this is in different war file to other methods)
This is would use the full spring stack (inc spring-mvc) with tomcat.
Any pointers please ?
You could use an Apache httpd, nginx or the like, and route URLs accordingly.
I dont think it is possible straight away as Tomcat starts different war files in different context paths. Only thing I can think of is deploying myRest.war and mySecondWarFile.war and adding a mapping for /ThirdMethod in myRest application itself and routing the request to /mySecondWar/ThirdMethod .

How to use in Tomcat a datasource without having to edit context.xml?

I have to deploy my web app to a shared server where I can't edit the context.xml file to set a new resource factory. Is there a way I could place ALL my hibernate datasource configurations in a file outside my .war, but still inside the deployment folder (the one I have access to).
My ultimate goal is to develop a "portable" web app, so I can easily migrate from one server to another, just editing manually my database configurations in a datasource file. Does anyone knows a functional way to do it?
Ps. I imagine Spring would help with this matter. But I don't feel like to set up it for a simple web app or just for this purpose.
According to http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#context.xml_configuration you can have a per-application context file as well, however that must of course be deployed inside your war file. Your best bet might be to modify your build file so that it uses the correct context.xml when creating the war.

Where to put application-wide settings in Java (Servlet)?

In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
Any hints? I've tried Google but found very little that seemed relevant - and what I did find appeared hideously over-engineered for my needs.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
That's the web.xml. You can define settings as <context-param> entries.
<context-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</context-param>
It's available by ServletContext#getInitParameter(). The ServletContext is in turn available anywhere.
String foo = getServletContext().getInitParameter("foo"); // Contains "bar"
You can also access it by EL.
#{initParam.foo} <!-- prints "bar" -->
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
As per the emphasis, I'd use a properties file for this particular purpose which is then placed in a path outside the WAR. You just need to add this path to the Java runtime classpath. Then you can obtain it as classpath resource:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
// ...
However, with the particular sole purpose to serve a DB connection, you're indeed better off with a servletcontainer-managed datasource as answered by Qwerky. All you possibly would need to configure is then just the datasource name.
If this is a web app then you'd be better served configuring the database connection as a resource on the server, then getting your app to retrieve it using JNDI. Your app server will have documentation on how to do this, its a basic task.
99% of serious web apps do this, the other 1% should.
You can have your application load an arbitrary external file by simply passing the path as a command-line parameter (to the servlet container startup script). Then store the values in the ServletContext

Deploying an identical war file with a different name causes the old one to stop?

We have an Apache tomcat server that runs a current web service. We were trying to deploy a second version (with a few tweaks) however when we copy the war file over, the first one stops working. Why??
Does your webapp contain context.xml configuration for Tomcat? If the two webapps use the same docbase then they are accessing the same folder.
If your application writes to a database, and another copy of it is competing for the same data in the same database, this can result in such behaviour. Does your application write to a "fixed" database? If so, you will need to create another database, or change the way the application deals with the database.
Is the Context root different in the war files. If not I believe the server will not validate the url correctly.

Is it possible to read a properties file from all .war files deployed in a JBoss container

I've managed to deploy a .war to the Jboss web container containing and read the pom.properties located under /META-INF/groupid-dir/artifactid-dir/
To access the file I've used the following code inside a JSP in the same war:
ServletContext servletContext = getServletConfig().getServletContext();
InputStream in = servletContext.getResourceAsStream("META-INF/maven/groupid-dir/artifactid-dir/pom.properties");
This works just fine. But I want to be able to dynamically read pom.propertes from ALL .war deployed in the container. Is this possible or do I only have access to the context for the one war holder my jsp?
-mb
Basically, your application is running on the same machine as the JBoss container, so accessing the files on the local filesystem should be possible, much in the same way you're accessing your own .properties file. I'm not familiar with anything that should prevent you from doing this.
If you want to access files within the war file, you'll need to use the java.util.zip package, as war files are of course normal zip files. Just a friendly reminder.
You will likely have to do something tricky like go through the JBoss MBeans. I realize this is vague, but consider looking into that approach. Here is a link on how to get the MBean server from an application within JBoss (add http://) www.jboss.org/community/wiki/FindMBeanServer (Stackoverflow is preventing me from pasting a link). I would imagine that you could find the Jboss Web mbean, peel off all web application mbeans, then ask each one for its classloader, then proceed to do what you already mentioned.
I don't think that reading a zip or using a jboss mbean are the right way.
I don't think it is tricky and you were on the right track by using ServletContext.getResourceAsStream.
You can probably use ServletContext.getResourcePaths, but several times it seems, to identify subdirectories groupid and artifactid.
Something like
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.properties")
or
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.xml")
for pom.xml
If the WAR file is exploded as folder , you should be able to use
String basePath=getServletContext().getRealPath("/");
This approach may not work if WAR file is in archive format
You can only look for resources in your current classpath. The normal operation of a web container is to create a specific classpath for each deployed artifact without access to the other artifacts deployed in the container.
This is very important to avoid artifact A which uses foo-1.0.jar to not accidentially use foo-0.9.jar which is deployed with artifact B.
Hence you will need ask the container for help. This in turn mean you need to write container specific code to do so. This will make you vendor dependent - you may not want that.

Categories