I have a Netbeans project, from which I build a .war file. I now deploy two instances of that war file on my glassfish server, each with a different context root, e.g. mydomain.com/abc and mydomain.com/def
This works fine but they are still operating on the same database, since I declare the persistence unit in the persistence.xml and the glassfish-resources.xml.
My glassfish-resources.xml file:
...
<jdbc-resource enabled="true"
jndi-name="jdbc/abc"
object-type="user"
pool-name="abcPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool
...
name="abcPool"
...
<property name="URL" value="jdbc:mysql://localhost:3306/abc"/>
...
</jdbc-connection-pool>
My persistence.xml file:
...
<persistence-unit name="abcPU" transaction-type="JTA">
<jta-data-source>jdbc/abc</jta-data-source>
...
</persistence-unit>
...
Does anybody have a solution on how to have two instances of one war file, operating on two different databases?
Is there maybe a way to upload a different glassfish-resources.xml and persistence.xml to each application, overwriting the packaged one?
It would be acceptable to change the module descriptors in the glassfish domain admin console once the application is deployed, if that is possible.
If screenshots from the glassfish domain admin console are needed, please write in the comments, I will add them.
Thank you in advance!
Easiest approach in my opinion would be to have two different builds.
Basically you may create two different .war files. Each one with a different persistence.xml file in it. One pointing to the JDBC resource ABC and the other one pointing to the JDBS resource DEF.
Build tools like gradle+Jenkins may support you with this.
You will find lots of information about similar tasks, if you search for how to create builds with a different configuration for testing vs. productive system. This is a very common task.
Here might be a starting point for what you are looking for:
Create multiple .WAR files with different dependencies in Gradle
At server level setup two Data sources pointing to different databases and go to the application instance and modify Resource reference pointing specific data source.
Related
I was under the impression that the libraries for both the database driver (postgres-x.x.jar'in my case) and the connection pooler (c3p0) had to reside in the container's lib (e.g. for Tomcat7, $CATALINA_HOME/lib).
However, the official C3p0 documentation doesn't provide any information with regards to put the connection pool's jar in the container vs having it in the application's war:
Place the files lib/c3p0-0.9.5.2.jar and lib/mchange-commons-java-0.2.11.jar somewhere in your CLASSPATH (or any other place where your application's classloader will find it). That's it!
A current issue in a new tomcat installation (java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector, when I have the mchange-commons-java dependency in the application's WAR and the c3p0 dependency in $CATALINA_HOME/lib) made me revisit this, but I can't find any authoritative information regarding where to put these libraries.
Usual application configuration
In my case the c3p0 configuration is made via spring bean within the application's classpath:
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
scope="singleton" destroy-method="close">
<property name="driverClass">
<value>org.postgresql.Driver</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.user}</value>
</property>
<property name="password">
<value>${jdbc.pw}</value>
</property>
...
<bean>
If I have multiple applications in the same Tomcat container, each will have one c3p0 bean like this contained in its war.
Memory Leaks?
The assumption for having the postgres.jar and c3p0.jar in the container's lib/ and not in the war was that the latter would cause memory leaks.
Leak in Postgres Driver
This user states that JDBC drivers register themselves in the JVM-wide singleton DriverManager which is shared by all web apps. If you have the same (as in class name) JDBC driver register twice from two different web apps, this might cause your problem. This is even more problematic if your web apps use different versions of the same JDBC driver.
Leak in c3p0
We moved c3p0 to $CATALINA_HOME/lib after this comment on Stackoverflow (we had a similar warning when undeploying an application).
Should they reside in Tomcat or the application's lib/ ?
Whether or not you need to put a jar in Tomcat's lib directory depends on whether Tomcat needs to know about it or not. And that depends on how you are configuring things.
As a general rule, if you are mentioning a class in a Tomcat config file, then that class (and those that it depends on) must be in Tomcat's lib directory.
For example, if you configure your DataSource in Tomcat's config files, then you need to make your driver class available to Tomcat. If instead you configure your DataSource within your application's code then you do not.
You do not specify how you are configuring C3P0, so we cannot tell you where the jar needs to be. Of course, if Tomcat needs it and it is not there, then you should expect to see an exception logged and things won't work properly.
I'm working in a Java Web Project.
I need to change the folder of the files "jdbc.properties" and "log4j.properties" depending of the environment, because testing, demo and release have diferent values for those files.
I have this folders and subfolders:
c:\myProject\conf\dev
c:\myProject\conf\test
c:\myProject\conf\demo
I need to put diferent jdbc.properties and log4j.properties files in each of those folders
c:\myProject\conf\dev\log4j.properties
c:\myProject\conf\dev\jdbc.properties
c:\myProject\conf\test\log4j.properties
c:\myProject\conf\test\jdbc.properties
c:\myProject\conf\demo\log4j.properties
c:\myProject\conf\demo\jdbc.properties
The three project are in the same Server and in the same Apache (It is a Web Project)
First i made some changes to use a windows system variable to get the parent folder (c:\myProject). To do that, i made this on Spring appContext file:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:${PARENT_FOLDER}/conf/dev/jdbc.properties</value>
</property>
</bean>
"PARENT_FOLDER" is defined on Windows environment variables/system variable
Those changes works OK.
But, as you can see, I always loking for file on "/conf/dev"
I need to make dynamic the "dev" part of the path.
I Can't use Windows environment variables/system variable because the 3 environments are deployed on the same Server.
I'm trying to use a "property" (using ) on web.xml, but I don't know how to find the property in my Spring appContext file.
I definy the property like this:
<env-entry>
<env-entry-name>ENVIRONMENT</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Dev</env-entry-value>
</env-entry>
But I don't know how to access "ENVIRONMENT" property on Spring
I don't know what to do. I a little desperate
Can someone help me?
Thanks and sorry for my poor english
Have you considered using JNDI?
With JNDI you will define the db connection properties inside tomcat itself. This way your spring configuration is independent of the environment and you can deploy the same war on all environments. See also this.
If you need to run it locally that you can always use the 'new' spring environment profiles feature.
Other option (if JNDI is not an option and assuming you use maven) is the maven replacer plugin where you will generate the db.properties at build time.
I'm trying to create an RPM-packaged Ear file that should be installable together with other RPM-packagesd Ear files in a JBoss container. (I could probably create a separate container within JBoss, but that's a lot of overhead for one Ear.) This works fine, except for one issue.
My problem is that this Ear file expose web services that use their own authentication policy (login-config.xml policy/application-policy/authentication/login-module). Now that multiple RPMs want to supply authentication information through this file, we get into conflict with the RPM spec rule that no file can be owned by more than one RPM package (and anyway whichever RPM goes last would clobber the previous).
Is there any way that the application-policy/authentication block can be declared in a separate file or in some manner that places it outside login-config.xml? For example, is it possible to declare additional security mbeans (in separate files) that refer to a separate login XML definition?
This is JBoss v4.2, but I would be willing to consider later if it solved this issue.
Update:
Lukasz rules. Below is working config!
<?xml version='1.0'?>
<server>
<mbean code="org.jboss.security.auth.login.DynamicLoginConfig"
name="jboss.security.tests:service=LoginConfig">
<depends optional-attribute-name="SecurityManagerService">
jboss.security:service=JaasSecurityManager
</depends>
<depends optional-attribute-name="LoginConfigService">
jboss.security:service=XMLLoginConfig
</depends>
<attribute name="PolicyConfig" serialDataType="jbxb">
<jaas:policy
xsi:schemaLocation="urn:jboss:security-config:4.1 resource:security-config_4_1.xsd"
xmlns:jaas="urn:jboss:security-config:4.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<jaas:application-policy name="mySecurityDomain">
<jaas:authentication>
<jaas:login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<jaas:module-option name="unauthenticatedIdentity">noone</jaas:module-option>
<jaas:module-option name="dsJndiName">java:/myDataSource</jaas:module-option>
<jaas:module-option name="principalsQuery">SELECT password FROM WebServiceUser WHERE userName=?</jaas:module-option>
<jaas:module-option name="rolesQuery">SELECT role, 'Roles' FROM WebServiceUser WHERE userName=?</jaas:module-option>
</jaas:login-module>
</jaas:authentication>
</jaas:application-policy>
</jaas:policy>
</attribute>
</mbean>
</server>
You can try and setup login module using DynamicLoginConfig service. I never use it but it looks like something that can help you. It allows you to create login module configuration
in different file and deploy it during application installation.
Here you can find more info about it:
Dynamic configuration of JAAS login
AS5: Specifying Security Domain Configuration
Configuration DynamicLoginConfig
10.5.2. The DynamicLoginConfig service
using DynamicLoginConfig
I am using JSF2 with Websphere 7 . I have created a shared lib successfully and have pointed application using Webpsphere Admin Console and it works successfully . But what we really want to do is to not have to point to that Shared Lib via WAS Admin Console but have some sort of application level configuration e.g in deployment.xml etc which we can point to the name of that Shared Isolated Lib and use it . I have gone through SO and google but not found any thing doing that . I however know that there are commercial application doing it but do not know how . This question from How can I specify a shared library reference at the web module level in Websphere 6.1 deployment descriptors? is closely what I am after but I not want to specify version numbers or jar names as the answer states
I found a way by simply following what WAS Admin Console was actually doing.
Create a deployment.xml in your EAR file if you do not have one already .
You will find a reference to class loader like below
<classloader xmi:id="Classloader_1311552732281" mode="PARENT_FIRST">
Modify it and add reference to the shared Liberary created on server like below
<classloader xmi:id="Classloader_1311552732281" mode="PARENT_FIRST">
<libraries libraryName="JSF2_SHARED_LIB" sharedClassloader="true"/>
</classloader>
#dbreaux has also shown a way .Accpeting my own answer as fits my needs better but big thanks to dbreaux too for advice.
Is the issue just that you don't want to have to configure each application separately, or that you don't want to use the admin console at all? You can associate a shared library with an entire server, which might be preferable to doing it for each app.
The other way to create those application associations is in the WebSphere-specific .xmi deployment files. These are created when you deploy but can also be included in WAR/EAR files. I don't know if that would help you at all. If it would, the official way to create them ahead of time is using one of the Deployment Tools, but since they're just XML, you may feel comfortable creating them manually.
To append extra details to Shahzeb's answer:
My environment: Websphere 8.5; Windows 7;(Eclipse Luna to generate testing .war file)
I have installed the war file exported from eclipse on websphere server by websphere console.
Then exported it again and unpack it to see what websphere automatically add to it to generate EAR.
[folder]META-INF
[folder]ibmconfig
[file]application.xml
[file]ibm-application-bnd.xmi
[file]ibm-application-runtime.props
[file]MANIFEST.MF
[file]was.module
[file]was.policy
[file]was.webmodule
[file]myWAR.war
And the file deployment.xml is placed in
..\ibmconfig\cells\defaultCell\applications\defaultApp\deployments\defaultApp\
whose content in form of
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1417052686904">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1417052686904" deploymentId="0" startingWeight="1" binariesURL="$(APP_INSTALL_ROOT)/[server service name]Cell/myWAR.ear" useMetadataFromBinaries="false" enableDistribution="true" createMBeansForResources="true" reloadEnabled="false" appContextIDForSecurity="href:[server service name]Cell/myWAR" filePermission=".*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755" allowDispatchRemoteInclude="false" allowServiceRemoteInclude="false" asyncRequestDispatchType="DISABLED" standaloneModule="true" enableClientModule="false">
<targetMappings xmi:id="DeploymentTargetMapping_1417052686904" enable="true" target="ServerTarget_1417052686904"/>
<classloader xmi:id="Classloader_1417052686904" mode="PARENT_FIRST"/>
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1417052686904" deploymentId="1" startingWeight="10000" uri="myWAR.war" containsEJBContent="0">
<targetMappings xmi:id="DeploymentTargetMapping_1417052686905" target="ServerTarget_1417052686904"/>
<classloader xmi:id="Classloader_1417052686905"/>
</modules>
<properties xmi:id="Property_1417052686904" name="metadata.complete" value="true"/>
</deployedObject>
<deploymentTargets xmi:type="appdeployment:ServerTarget" xmi:id="ServerTarget_1417052686904" name="server1" nodeName="[server service name]"/>
</appdeployment:Deployment>
(Since I have no reputation, I have to do it all in text.. )
I have a JEE application that runs on WAS 6. It needs to have the class loader order setting to "Classes loaded with application class loader first", and the WAR class loader policy option set to "Single class loader for application".
Is it possible to specify these options inside the EAR file, whether in the ibm-web-bnd.xmi file or some other file, so the admin doesn't need to change these setting manually?
Since the app is deployed via an automated script, and the guy who is in charge of deployment is off site, and also for some other political reasons, this would greatly help!
Thanks to #Matthew Murdoch's answer, I was able to come up with a solution. Here it is, in case it helps someone else.
I created a deployment.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1241112964096">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1241112964096" startingWeight="1" warClassLoaderPolicy="SINGLE">
<classloader xmi:id="Classloader_1241112964096" mode="PARENT_LAST"/>
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1241112964096" startingWeight="10000" uri="AGS.war">
<classloader xmi:id="Classloader_1241112964097"/>
</modules>
</deployedObject>
</appdeployment:Deployment>
Make sure to change the name of your WAR file(s) to match (mine is called AGS.war).
I also changed the numbers in the xmi:id attributes, to be sure they are unique, though I'm not sure it it really matters that they be unique across applications.
Then, I put the deployment.xml file in the root of my EAR file, via ANT:
<ear destfile="${artifactsDir}/${earName}.ear" appxml="${projectName}_EAR/application.xml">
<fileset dir="${artifactsDir}" includes="${warName}.war"/>
<fileset dir="${projectName}_EAR/" includes="deployment.xml"/>
</ear>
Edit (2): The WebSphere Application Server Toolkit (AST) is a tool you can use to enhance an EAR file with this information (see for example the 'Configure an Enhanced EAR' section in this document).
Edit (1): This post suggests that the 'Classes loaded with application class loader first' (the PARENT_LAST setting) can be set in the deployment.xml file within the EAR.
If you have control over the automated deployment scripts this can be done. Below is some wsadmin jython code for setting the web module class loader order to 'Classes loaded with application class loader first' (interestingly the setting is called PARENT_LAST which is what it was labelled in previous versions of the admin console...).
wsadmin example (jython):
def getWebModule(config, applicationName):
webModules = config.list('WebModuleDeployment').
split(system.getProperty('line.separator'))
for webModule in webModules:
if (webModule.find(applicationName) != -1):
return webModule
return None
applicationName = "<Your application name here>"
webModule = getWebModule(AdminConfig, applicationName)
if (webModule != None):
AdminConfig.modify(webModule, "[[classloaderMode PARENT_LAST]]")
AdminConfig.save()
else:
print "Error: Cannot find web module for application: " + applicationName
Check out this link. There are different ways to set class loader policy using Jython based on your server version -
http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frxml_7libapp4.html
Similar to the answer from pkaeding, I discovered as follows, not specific to a particular .war by name, but useful when applying to whatever is the default .war in the .ear file. (.ear files with one .war file in them have only that .war, so naming the .war isn't necessary in the entry.) This approach may be good for situations where you may need to re-name of the .war project later for some reason, and so you wouldn't need to worry about updating the deployment.xml file. I found the deployment.xml file buried inside a cell reference directory trail; dunno if it's fine as shown when the file is placed at directory level META-INF and no deeper.
In my particular case, I found deployment.xml in my .ear project at:
<project_root>\META-INF\ibmconfig\cells\defaultCell\applications\defaultApp\deployments\defaultApp\
The content of the file looks a lot like:
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1262775196208">
<deployedObject xmi:type="appdeployment:ApplicationDeployment"
xmi:id="ApplicationDeployment_1262775196208" startingWeight="10">
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_LAST" />
</deployedObject>
</appdeployment:Deployment>
The line:
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_LAST" />
originally read:
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_FIRST" />
Note no reference to any .war is being made. As pkaeding mentioned, you shouldn't expect the various id numbers to be the same for you.