How to eliminate hardcoded values in the web.xml - java

Let's say that I have something like this in my web.xml file.
<filter name="foo">
<init-param>
<param-name>fooBarUrl</param-name>
<param-value>http://foo.bar.com</param-value>
</init-param>
</filter>
Say there are different url values (for the param-value above) for dev/test/production. Is there a way that you can use filters and/or profiles in the pom to eliminate the need for changing this every time the application moves to a different stage? I.E. for dev it would be http://localfoo.com, and for test it would be http://testserver.com, etc.

You can use Maven's resource filtering ro replace properties with values at build time, e.g. by using different Maven profiles to set the properties values.
On the other hand you could use servlet parameters and move them to the context configuration, so your web.xml references them and they are actually configured in the application server where the .war file is deployed. That way, the application server administrator can reuse the same war file for each environment by just configuring it at server level.
In Tomcat for example, you can set the values in the context.xml file:
<Context>
...
<Parameter name="targetURL" value="http://testserver.com"
override="true"/>
...
</Context>

maven-replacer-plugin is what we use in our project for doing such text, pattern and version replacements during build time.

Related

Set a path to an outside-the-app file in web.xml

I'm working in a java webapp that uses Picketlink package. This package needs a config file ( picketlink.xml ) that is located in WEB-INF directory by default. This app will be hosted in 3 different linux jboss servers/environments (development, testing and production).
This configuration file is different for each env.
It's a project requirement that I have only one single build (single artifact) for all envs, so env-specific stuff must be in the server (can't use profiles). So, I need to store this file in the server itself and reference it from inside the app.
The documentation recommends that I use a context-param inside my web.xml to point to this external file:
<context-param>
<param-name>CONFIG_FILE</param-name>
<param-value>/path/to/picketlink.xml</param-value>
</context-param>
I just can't make it work as the app does not find the file.
What would be the right way to write this path? I wanted something like this:
<context-param>
<param-name>CONFIG_FILE</param-name>
<param-value>home/user/picketlink_config/picketlink.xml</param-value>
</context-param>

Deploying another servlet to a wildfly instance

I'm trying to deploy a second web application to a Wildfly server currently hosting a single application. I've made the following modifications to standalone.xml (see Accessing Multiple web applications on Jboss7 or Wildfly - my need is essentially the same):
Under <subsystem xlmns="urn:jboss:domain:undertow:8.0>, added
<server name="dispatch-server">
<http-listener name="default" socket-binding="dispatch"/>
<host name="dispatch-host" default-web-module="Dispatch.war" alias="Dispatch.com">
</host>
</server>
Next, under <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">, added
<socket-binding name="dispatch" port="${jboss.https.port:8081}"/>
Finally, under <Deployments>, added
<deployment name="Dispatch.war" runtime-name="Dispatch.war">
<fs-archive path="${jboss.home.dir}/standalone/deployments/Dispatch.war" />
</deployment>
web.xml content for the deployed Dispatch.war:
<servlet>
<servlet-name>DispatchServlet</servlet-name>
<servlet-class>blah.blah.blah.DispatchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I wrote a little application to test connecting to the servlet, using "http://localhost:8081", but I get an HTTP 404 error. I've tried additionally with "http://localhost:8081/DispatchServlet" with no changes.
I found other tutorials mentioning the need for a jboss-web.xml file bundled with Dispatch.war, so I added a barebones one that looks like:
<jboss-web>
<context-root>/</context-root>
</jboss-web>
It didn't impact the behavior I was seeing. I also tried changing the context-root to "DispatchServlet" and then hitting "http://localhost:8081/DispatchServlet" with nothing.
Is there something obvious I'm goofing on?
I think you are over complicating the issue. If you want to deploy multiple web apps, just drop ear war within the deployments directory. When they deploy the log shows their context path, then access any content relative to that path, e.g
/war1/DispatchServlet
/war2/DispatchServlet
If using different paths is not acceptable, then in order to do as you are trying, you need to follow the guides that explain how to use ROOT.war files and the associated changes to standalone-full.xml to disable the inbuilt default

How do I use Multiple Substitutions in Lookups for Log4J 2 configurations? Is it possible?

I have a situation in which I want Log4J 2 to determine which directory to use for logging. The pseudocode is as follows:
property LOG_DIR = "./logs" // default
if (isDIR(${env:LOG_DIR}) {
LOG_DIR = "${env:LOG_DIR}"
} else if (isDir(${sys:catalina.base}) {
LOG_DIR = "${sys:catalina.base}/logs"
}
The configuration I have for properties (in log4j2.xml) is as follows:
<Configuration status="DEBUG">
<Properties>
<Property name="LOG_DIR">${sys:catalina.base}/logs:-logs</Property>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %t/%c:%L | %m%n</Property>
<Property name="JAVA_HEADER">${java:version} - ${java:os}</Property>
</Properties>
<!-- Other configuration here -->
</configuration>
What I think it should look like:
<!-- Is this permitted? What happens if there's no Catalina Base AND no LOG_DIR env var? -->
<Property name="LOG_DIR">${env:LOG_DIR}:${sys:catalina.base}/logs:-logs</Property>
What I'm not sure on is how to get both ${env:LOG_DIR} and ${sys:catalina.base} options in the LOG_DIR property in configuration (before the default of logs). Is this even possible without a programmatic solution? (I'd like to avoid a programmatic solution as this config will be a template for multiple projects, some of which are libraries in SE applications. I'd like to avoid including a library that is only for configuring Log4J.) As far as I know, there can be only one lookup before the default. I don't know if nesting or chaining is permitted.
Today, I encountered the same problem and i stumbled upon this question. I tried at my own end and i was successfully able to solve the issue and accomplish the desired result.
<Property name="LOG_DIR">${env:LOG_DIR:-${sys:catalina.base:-/logs}}/somexyz.log</Property>
sys: It stands for System environment variable, this is for whole PC or your current user.
env: It is the run time environment variable which you configure in runner in Intellij or similar.
According to log4J2 lookup official site: The general format of Lookup is ${sys:SOME_SYS_PATH:-default_path} or ${env:SOME_ENV_PATH:-default_path}.
Now as per your requirement, You want to see if a file path is
configured in runtime environment or not, if yes then save all logs
event data at that place. If no file is configured in runtime
environment then look for system environment, if path is configured
there then save all logging information there else save all logging
information to a default path i.e /logs.
Use below code and it will work for you.
<Property name="LOG_DIR">${env:LOG_DIR:-${sys:catalina.base:-/logs}}/somexyz.log</Property>
If file path is configured in runtime environment then save it there, else check if path is configured in system environment(PC) and save there , else save it in default path /logs.
The previous answer did point out correctly that a lookup expression can be used as the default value inside another lookup expression. My requirement was to allow the configuration to reside outside of WEB-INF and allow two different locations for that. Luckily, this also works for the web.xml configuration:
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///${sys:myapp.home:-${sys:user.home}}/myapp/log4j2.xml</param-value>
</context-param>
If system property myapp.home is not set, user.home will be used instead. This overrules the default location (WEB-INF/log4j2.xml). If the indicated file doesn't exists, only the search on the classpath is left. So I put a fallback configuration into WEB-INF/classes.

How to pass the -D parameter when multiple WAR files are running?

When multiple WAR files are running under tomcat,
each WAR is expecting a
-Dconfig-path=/path/app.conf.ini
Is it possible to pass a unique -D Parameter value to each of the running applications?
tomcat
webapps
APPLICATION_1.war -Dconfig-path=/path/app.conf1.ini
APPLICATION_2.war -Dconfig-path=/path/app.conf2.ini
APPLICATION_3.war -Dconfig-path=/path/app.conf3.ini
You can add all the configuration properties in one file and pass it as command line parameter while starting tomcat. All those properties will be available to all .war files.
But if all the war files are using same property name then you have to modify the property name in config file and your code.
For example: If you are using app.version=1.1 for 1st war and 2.1 for 2nd war then you have to add them like
Firstwarname.app.version=1.1
SecondwarName.app.version=2.1
Accordingly, your code needs to be modified to access properties.
I found a way
In the web.xml added this:
<context-param>
<param-name>config-path</param-name>
<param-value>/path/app.conf1.ini</param-value>
</context-param>

Maven copying applicationContext.xml from src/main/resources to target/myproject/WEB-INF

At the moment, the default I think, it copies to
target/myproject/WEB-INF/classes
so when deploying it does not pick up the context.
Also, i want to reference a server specific config file database.properties, I want to put it in tomcat/conf and then reference it in applicationContext.xml, how can I do this ?
Also(2), I am under the impression that this is a fairly standard and decent way to set things up - please correct me if I am wrong.
edit
for the server specific config file I user this
<context:property-placeholder
location="file:${catalina.home}/conf/database.properties"
ignore-unresolvable="true"
/>
If you need to keep applicationContext.xml as a classpath resource, you can configure ContextLoaderListener to pick it from the classpath by adding the following lines to web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
It's much easier than configuring Maven to copy it to WEB-INF.
Regarding the second question, you can configure PropertyPlaceholderConfigurer or <context:property-placeholder> to load .properties file from a file system.
For your title question: Often in a .war maven module, you'll put web related resources under src/main/webapp instead of src/main/resources. Then the maven plugin will pick them up automatically because it matches convention. So, move your applicationContext.xml to src/main/webapp/WEB-INF
Another option is to configure the webResources as described in the documentation
For the second question you can look at a PropertyPlaceHolderConfigurer. You'll just have to get the path correct.

Categories

Resources