How to set environment variables in JBoss - java

We are developing an application that is deployed in a JBoss.
we would like to define a properties files like this:
URL_DEVELOPMENT.properties = ...
URL_TEST.properties = ...
URL_PRODUCTION.properties = ...
and define an environment variable in the JBoss which contains the information about the execution context
for example --> ENVIRONMENT = DEVELOPMENT
Anyone knows:
How to set environment variables in JBoss.
How to get these variables from an applicacion deployed in JBoss in runtime execution?

The easiest and most straight forward way is to log into jboss web admin:
www.yoururl:9990
Then under configuration, look for system property.
At runtime, it is very easy: System.getProperty(yourPropertyKey) and the good thing is that a change in any of these properties is reflected immediately at runtime.
The other scenario is to open up standalone.xml
<server ...>
<system-properties>
<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>
</system-properties>
</server>
The other option is to read on jboss cli and configure system properties from there. (Only useful if you want to work with remote jboss and you cannot ssh into the server, and you cannot access the web admin)

Related

Tomcat set application context using configuration (not war name)

My question is this - Say I have a war file called my-app-123.war. I want to deploy it on a Tomcat server (9.0.x), let it auto unpack.
The application would then be accessible by http://localhost:8080/my-app-123
Is there a way, without renaming the war file, to make the application accessible from http://localhost:8080/my-app?
I will preface this by saying I realize the easiest solution is to just name the war file. I'm curious if there is a way to do this in Tomcat configurations.
I did do this already (inside the host section of my server.xml file):
<Context path="/my-app" docBase="my-app-123"></Context>
But I read this online (https://tomcat.apache.org/tomcat-7.0-doc/config/context.html) in the path variable description:
Even when statically defining a Context in server.xml, this attribute must not be set unless either the docBase is not located under the Host's appBase or both deployOnStartup and autoDeploy are false. If this rule is not followed, double deployment is likely to result.
And I can access the app now at http://localhost:8080/my-app and http://localhost:8080/my-app-123, which isn't a real solution.
The following works for Tomcat deployments I have used - there are no double-deployment issues.
In the example I will use here, I have a simple "hello world" webapp in TomcatDemo-1.0-SNAPSHOT.war. It is deployed on Tomcat 9.0 in the standard location (webapps directory).
I want the application's context path to be /my-foo-app.
I use the following context entry in server.xml:
<Context path="/my-foo-app" docBase="TomcatDemo-1.0-SNAPSHOT.war"></Context>
I also use the following in server.xml:
<Host name="localhost"
appBase="webapps"
deployOnStartup="true"
deployIgnore="TomcatDemo-1.0-SNAPSHOT.war"
unpackWARs="true"
autoDeploy="false">
The important item here is deployIgnore. It is described here:
https://tomcat.apache.org/tomcat-9.0-doc/config/host.html#Automatic_Application_Deployment
When using automatic deployment, the docBase defined by an XML Context file should be outside of the appBase directory. If this is not the case, difficulties may be experienced deploying the web application or the application may be deployed twice. The deployIgnore attribute can be used to avoid this situation.
Alternatively, if you don't mind about automatic start-up deployments, you can set deployOnStartup="false" - in which case you don't need deployIgnore.
In these scenarios, the web app is available only here:
http://localhost:8080/my-foo-app/ <-- OK
Otherwise, as you note, with double-deployment the web app would also be available here (and you would see two exploded directories in webapps):
http://localhost:8080/TomcatDemo-1.0-SNAPSHOT/ <-- BAD!
Hope that helps.
Finally, it can get a little complicated, with all the various auto-deployment options. This page provides a set of summary tables and explanations:
https://tomcat.apache.org/tomcat-9.0-doc/config/automatic-deployment.html

Static ressources: where define context aliases with tomcat

I am looking for a way to access static resources (e.g. video files) from my web app JEE.
In my local environment, I added an aliases attribute in the context of my webapp under the config of my tomcat server in Eclipse. This works verywell.
Doing that my context in Eclipse Tomcat server.xml is:
<Context path="/maWebApp" docBase="path/vers/ma/webApp" aliases="/video=/chemin/sur/mon/PC">
Now I want to do the same thing in my production server. But:
under this server (linux, tomcat7), the file etc/tomcat7/server.xml doesn't contains any "Context" for my webapp. I suppose that the context is created automatically during webApp deployment
if I add a "Context" for my application, in order to define the "aliase" attribute, my server tomcat doesn't restart anymore.
So my question is: where should I define the "aliase" attribute when I use Tomcat7 and when I deploy my application with .war generated from Eclipse.
Important note: I don't want to manage the aliases in the webapp, because the aliases change depending on the server (local dev or prod).
Thank you very much for any advise and best practise,
Have a good day!
Adrien
You should be able to add a context attribute to your server.xml.
https://tomcat.apache.org/tomcat-4.1-doc/config/context.html
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" /> <Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
/> <Listener
className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"
/>
<Context path="/maWebApp" docBase="path/vers/ma/webApp"
aliases="/video=/chemin/sur/mon/PC" />
</Server>
My tomcat is starting fine with this.
What error do you have when starting it with the "< Context .. />" attribute ?
Take a look over here: https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context
Defining Context elements in server.xml is discouraged. Instead put context.xml in
$CATALINA_BASE/conf/[enginename]/[hostname]/
enginename will most likely be Catalina, so e.g if your tomcat directory is /opt/tomcat7/ and your hostname is www.mysite.com then put the context in this directory:
/opt/tomcat7/conf/Catalina/www.mysite.com
And rename your context file maWebApp.xml
Update: Unless you need the static resources to be available to your app, and if only you need a virtual directory for visitors to access static resources you do not need the aliases attribute. Create a context in a file named video.xml in the same directory as above:
<Context docBase="/chemin/sur/mon/PC/" path="/video/"></Context>
Static resources will then be available at www.mysite.com/video

Set specified system property for web application

I have an JavaEE application which needs some certain system properties configured during the runtime.
During the development phase, we set the properties in the .pom.xml to make it work:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<systemProperties>
<xxx>true</xxx>
</systemProperties>
</configuration>
</plugin>
However I wonder how about if we deploy the application in the production environment?
I have though of set the property during the initialization of the servlet, but it seems that I can not modify the system property once the jvm is runing(from this post):
The JVM memory parameters for a Hotspot Java implementation can only
be set via the command line options when the JVM is launched /
started. Setting them in the system properties either before or after
the JVM is launched will have no effect.
And I have tried to set the properties in the web.xml (here):
<env-entry>
<env-entry-name>xx</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>xx</env-entry-value>
</env-entry>
But it seems like it does not take affect.
Then I wonder how to solve it?
BTW, in the production environment we may run more than one application under a shared tomcat, so we prefer to set the properties under the application context only.
Environmental Entries
The <env-entry> won't make it for you because Environmental Entries are availble through JNDI and not through the System properties facade.
So if you configure some entry as below in your deployment descriptor file:
<env-entry>
<env-entry-name>myProperty</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>some-value</env-entry-value>
</env-entry>
Accessing the property in codebase as below will return a null reference:
System.getProperty("myProperty");
Though it should be retrieved with a context lookup as follows:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Look up for your property "myProperty"
String myPropertyValue = (String) envCtx.lookup("myProperty");
The main advantage is that you will be able to have a property which value will vary from one web application to another. But this way, and as the amount of your deployed artifacts will rise, it will be hard to maintain this and I think, based on my humble experience, it is not advised for production environments.
System Properties
If you are targeting a production environment, I advice using system properties (Your code source should then be updated to follow the style).
Since you are using Tomcat as an Application Server, you have one way that will let you have centric property definition, that is to declare a file named setenv.sh (.bat for Windows OS) where you export all the needed System Propeties, e.g of content it might have:
export CATALINA_OPTS="$CATALINA_OPTS -DmyProperty=some-value"
There is no more additional configuration needed, and this file will be processed by default when launching the JVM instance if present under $CATLINA_HOME/bin or $CATLINA_BASE/bin.
you are confusing web.xml env entry with system environment with java system properties
ask your ee server admin to add those in server definition such as
-Dpropname=true

system-properties in JBoss AS7

In the standlone.xml file in JBoss AS7, I have set the variable my.dir in system properties as
<system-properties>
<property name="my.dir" value="D:\\mylocation"
</system-properties>
Now I am trying to use this variable to specify the location of the keystore file in the standalone.xml in the following way
certificate-key-file="${my.dir}\cert\mycert.keystore"
However, while starting JBoss, I am getting IO exception as JBoss is not able to locate the path. Could you please let me know if I am doing anything wrong?
As far as I know the ssl element in the jboss web subsystem does not support system property substitution (yet). You have 3 choices:
Use an absolute path
Use a relative path from $JBOSS_AS7\bin location
Store the certificate in the default location where JBoss looks for them - ${user.home}/.keystore which is the operating system home directory the user running jboss.web.
See more details on jboss.web ssl configuration here.

Tomcat production / dev environments

In PHP development, its possible to determine whether or not the app is running in a production or a development environment from the servers 'environment' variable.
Is there a similar variable available on tomcat servers, or is there a better way of targetting applications for production and development?
Every Tomcat instance we have has an isProduction flag defined in the GlobalNamingResources section of the server.xml file.
server.xml:
<Server ...>
...
<GlobalNamingResources>
<Environment name="isProduction" value="false" type="java.lang.Boolean" override="false" />
</GlobalNamingResources>
<Service name="Catalina">
... etc ...
</Service>
</Server>
This allows the property to be available throughout the app by creating a property in the context.xml that references the resource:
context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context ...>
<ResourceLink name="isProduction" global="isProduction" type="java.lang.Boolean" />
...
</Context>
To fetch the value:
public boolean isProduction() {
Object o;
try {
o = (new InitialContext()).lookup("java:comp/env/isProduction");
} catch (NamingException e) {
o = Boolean.FALSE; // assumes FALSE if the value isn't declared
}
return o == null ? Boolean.FALSE : (Boolean) o;
}
You can't do such thing by default.
In any case, do not rely on the container to determine whenever the app is in the environment X. I'd say that you should do it using one of the following methods (in order of preference):
Use whatever your build tool provides. E.g.: use maven profiles. http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Use a property file for the app with a "mode" property.
Pass a -Dmyproject.mode=XXXX property to the JVM
Use an OS system property
I encourage you to use something like #1. For sure you are using some kind of tool to build your app (Ant, SBT, etc).
Imagine if by mistake somebody reinstall Tomcat, remove the OS properties or similar. Your app might run in prod mode.
You could set up OS environment variables in tomcat startup scripts (run.sh at linux environment, for example) and read them from your program. Also you could setup java environment variables (like this: Passing environment variables to a JVM, in a platform-independent manner).
I personally use different property files for dev/prod/etc and read this variable for property file. Only required property file is deployed.

Categories

Resources