Best way to configure a Java enterprise application - java

I have a set of EJBs and other Java classes which need to be configured differently based on the system environment in which they are deployed: production, test, or lab. The configuration information includes stuff like URLs and database connection information.
We'd like to deploy the same exact product (EAR file) in each environment, and have the code then figure out where it is and what its configuration should be, without having to reach out to each deployment server in each environment to make changes.
What is the best way to configure all these components in a centralized, reliable, easy-to-maintain fashion?
Thanks for your thoughts.

The best, IMHO, is to use JNDI entries.
You may have to recode some parts of your application in order to use theses entries instead of plain vars, but with this setup:
Configuration is server-independant: each vendor provides its own implementation, but spec is a standard.
In a clustered environment, config can be persisted in a cluster-wide JNDI tree (see JBoss)
Configuration can be changed thru webadmin without restarting server.

How database connection pool information is stored / configured depends on the app server vendor. Put other variable stuff in property files on the classpath.

If you are deploying the exact same EAR to three different instances of a certain container than you will have to edit the deployment settings as there is no way that the deployment process could have any idea about which one of your three versions you would like to use at a particular deployment.
Deployment settings should go into JNDI entries as Piere-Yves said above.
If I were you, I would have my deployment-script (Ant?) properly populate the JNDI entries depending upon which environment you are deploying to.

Related

Websphere Server Profile for different node and cell name

I'm relatively new to Websphere. I have created a WAS ( Websphere Application Server 8.5) profile configuration on local, manually from scratch which contains multiple data sources, queues, connection factories and activation specifications. ( Windows 7 PC). I backed this up using backupConfig.bat. I wish to replicate this profile configuration on another system where the Websphere Application Server (installation cannot be altered) has a different Node and Cell name. Is there a way where I can replicate it , without having to manually create the resources again,one-by-one , in the local WAS profile on the new system? When I googled this, it threw up the manageprofiles command, though I am not sure if it's backup option will work in my case. Thanks in advance.
If these are simple queues, datasource etc you can use Property based configuration - see Using properties files to manage system configuration.
You export configuration from one cell and import to the other.
If you have few elements you can use WebSphere Configuration Migration Tool (Eclipse plugin), which will allow you to select graphically which resources to move - it generates jython script that you can execute on target environment.

Avoid project's directory - Java EE app

I am writing and small app using Java EE. I am using Apache Tomcat v 7 and Eclipse as IDE. When I Run the project (Run on server) I get :
http://127.0.0.1:8080/java-web/lis
(That's fine)
But I don't know If there is some way to rewrite the [java-web] dir just to get :
http://my-local-app.dev/list
I suppose there is some way like in Apache Server using confing files and enabling
the mod_rewrite.
I'll apreciate your help. Thanks
In short: All of the pieces you want to change are components of your deployment environment. Unless you have a specific need to override them, it's usually easiest during development to use the URLs that are a little less pretty.
If you do want to alter them, you need to familiarize yourself with what the various parts of an HTTP URL mean. What you have in your test environment is this:
http:// 127.0.0.1:8080/java-web/list
protocol host port path
You could insert an entry into your hosts file listing my-local-app.dev at 127.0.0.1, but that would not change the port or the path.
The port is determined when Tomcat starts up and is 8080 by default. The general port for HTTP is 80, but specific permission is required to bind to ports below 1024. On Linux, the authbind package makes this pretty easy; on Windows, the necessary steps will depend on your version and configuration (e.g., if you have a Group Policy).
In Tomcat, Web applications are prefixed with their names in the path; it looks like your (hypothetical?) application is named java-web.war. You can install an application as the "root application", but this requires a little bit more configuration and is generally skipped in development.
All of this can indeed also be done using something like mod_rewrite, but that seems like overkill to have slightly prettier URLs for your dev machine.
If you want your application to respond to the my-local-app.dev, you need to purchase the "my-local-app.dev" domain and get a Java web hotel running on it.
If your web application is named "java-web" and you do not want the URL to reflect that, you need to tell Tomcat that you want your application deployed at the ROOT location where the name of the web application is not present in the URL. This is typically done in the deployment stage but unfortunately there is no standard location to say this for WAR files so this is vendor dependent. For example does Glassfish use an extra XML file in your deployment.
I believe Tomcat supports this for ROOT.war files. If not, you probably needs to set the META-INF/context.xml file. See https://tomcat.apache.org/tomcat-7.0-doc/config/context.html for details on what to put in this file - especially the context path.

Glassfish: modify deployment descriptors for EAR during deployment

After several days of searching, trying and head-banging, I post this question to SO although it seems to be answered already.
Here is the scenario:
I have an EAR application containing (for the moment) one WAR and one EJB module. The EJB module uses JPA (persistence.xml) and some Stateless Session Beans are exposed via Web Services. The web services use Basic authentication with a jdbc realm. The web module uses form authentication with the same realm.
The requirement:
I need to be able to deploy this application either on different servers (dev/test/prod) or on the same server (or cluster) with different deployment descriptors. The deployment settings that need to be different in each application instance are:
The jta-data-source in persistence.xml
The realm-name in web.xml
The javax.faces.PROJECT_STAGE in web.xml
The webservice-endpoint\endpoint-address-uri and login-config\realm in glassfish-ejb-jar.xml
The context-root in application.xml (i could move it to web.xml if it made any difference, see below)
The realm in glassfish-application.xml
During my research, I managed the following:
I can override the javax.faces.PROJECT_STAGE using asadmin set-web-context-param
I can override all settings in glassfish-ejb-jar.xml using a deployment plan during asadmin deploy
The same applies for glassfish-application.xml
I can probably override context-root during asadmin deploy (I don't know how would this work with more than one web modules in the EAR)
So far so good. This leaves me with the following problems:
How can I easily modify the the realm-name in web.xml?
How can I easily modify the jta-data-source in persistence.xml?
By easily I mean during deployment or using something similar to a deployment plan jar. Maintaining multiple copies of ejb.jar or war just with a modified .xml file is not an option.
Just to be clear, the need is to have different databases (either in different stages of development or for different customers) using the same application. The application uses one persistence-unit but it needs to point to different databases (hence the jta-data-source). The realm is a jdbc realm (on the same database) that also needs to be different per application instance.
Any help or pointer would be greatly appreciated.
Have you thought about preparing templates for the deployment descriptors, and populating them with value from property file during build? If you are using ant, you can use the expandproperties filter.
You can do all those things with a deployment plan jar.
It looks like the content of the deployment plan jar is pushed into archive/directory tree of the application BEFORE any of the heavy lifting associated with deployment happens.
See
http://java.net/projects/glassfish/sources/svn/content/trunk/main/appserver/deployment/javaee-core/src/main/java/org/glassfish/javaee/core/deployment/DolProvider.java
and
http://java.net/projects/glassfish/sources/svn/content/trunk/main/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/archivist/Archivist.java

Can tomcat store variables/properties that get called from a war

I want to be able to deploy my app using ANT to Tomcat.
I don't want the process to be any different for dev and prod. However the two use different databases i.e. myapp and myapp-dev
How can I make this happen? Can I store a variable in the different tomcat containers and make the application call the name of the database from Tomcat.
Or if what I am asking is ridiculous what is the generally accepted way to achieve deploying to dev and prod with the same process.
The generic way is to put the configuration string in a JNDI entry.
If JNDI is not a possible solution, then a property file in the right location (so it shows up in the classpath of the WAR files) is also useful, but needs careful documentation.
Have you considered letting the web container manage the database connection pool, so you only need a single one pr container, which then can be retrieved through JNDI?

JMX Remote Deployment Architecture

I'm reading up on JMX for the first time, and trying to see if its a feasible solution to a problem we're having on production.
We have an architecture that is constantly hitting a remote web service (managed by a different team on their own servers) and requesting data from it (we also cache from this service, but its a sticky problem where caching isn't extremely effective).
We'd like the ability to dynamically turn logging on/off at one specific point in the code, right before we hit the web service, where we can see the exact URLs/queries we're sending to the service. If we just blindly set a logging level and logged all web service requests, we'd have astronomically-large log files.
JMX seems to be the solution, where we control the logging in this section with a managed bean, and then can set that bean's state (setLoggingEnabled(boolean), etc.) remotely via some manager (probably just basic HTML adaptor).
My questions are all deployment-related:
If I write the MBean interface and impl, as well as the agent (which register MBeans and the HTML adaptor with the platform MBean server), do I compile, package & deploy those inside my main web application (WAR), or do they have to compile to their own, say, JAR and sit on the JVM beside my application?
We have a Dev, QA, Demo and Prod envrionment; is it possible to have 1 single HTML adaptor pointing to an MBean server which has different MBeans registered to it, 1 for each environment? It would be nice to have one URL to go to where you can manage beans in different environments
If the answer to my first question above is that the MBean interface, impl and agent all deploy inside your application, then is it possible to have your JMX-enabled application deployed on one server (say, Demo), but to monitor it from another server?
Thanks in advance!
How you package the MBeans is in great part a matter of portability. Will these specific services have any realistic usefulness outside the scope of this webapp ? If not, I would simply declare your webapp "JMX Manageable" and build it in. Otherwise, componentize the MBeans, put them in a jar, put the jar in the WEB-INF/lib and initialize them using a startup servlet configured in your web.xml.
For the single HTML adaptor, yes it is possible. Think of it as having Dev, QA, Demo and Prod MBeanServers, and then one Master MBeanServer. Your HTML Adaptor should render the master. Then you can use the OpenDMK cascading service to register cascades of Dev, QA, Demo and Prod in the Master. Now you will see all 5 MBeanServer's beans in the HTML adaptor display.
Does that answer your third question ?
JMX is a technology used for remote management of your application and for a situation for example when you want to change a configuration without a restart is the most proper use.
But in your case, I don't see why you would need JMX. For example if you use Log4j for your logging you could configure a file watchdog and just change logging to the lowest possible level. I.e. to debug. This does not require a restart and IMHO that should have been your initial design in the first place i.e. work arround loggers and levels. Right now, it is not clear what you mean and what happens with setLoggingEnable.
In any case, the managed bean is supposed to be deployed with your application and if you are using Spring you are in luck since it offers a really nice integration with JMX and you could deploy your spring beans as managed beans.
Finally when you connect to your process you will see the managed beans running for that JVM. So I am not sure what exactly you mean with point 2.
Anyway I hope this helps a little

Categories

Resources