JNDI DataSource: migrating from Weblogic to Jboss 7 - java

I migrate my Weblogic application to JBoss 7 and I need that my migration code could be runnable on these both servers. JNDI name of WebLogic datasource is :
jdbc/powds
JNDI name of Jboss datasource is :
java:/powds
I've already known that JNDI syntax in JBOSS 7 is another and starts with the prefix "java:". In WebLogic application I use JNDI name in different files like web.xml and persistance.xml.
In code I use :
static final String dataSourceName = "jdbc/powds";
I read this article JNDI path Tomcat vs. Jboss and trying to configure my xmls descriptors files.
So finnaly I have error Required services that are not installed:" => ["jboss.naming.context.java.jdbc.powds"].
How I can avoid this error? How I can configure persistance.xml file to use different JNDI names depends on running the application server.
my web.xml file is:
<resource-ref>
<res-ref-name>jdbc/powds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
my jboss-web.xml file is:
<resource-ref>
<res-ref-name>jdbc/powds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/powds</jndi-name>
</resource-ref>
my weblogic.xml file is:
<resource-description>
<res-ref-name>jdbc/powds</res-ref-name>
<jndi-name>jdbc/powds</jndi-name>
</resource-description>
my weblogic.xml file is:
<resource-description>
<res-ref-name>jdbc/powds</res-ref-name>
<jndi-name>jdbc/powds</jndi-name>
</resource-description>
my persistance.xml file is:
<persistence-unit name="powpu" transaction-type="JTA" >
<jta-data-source>jdbc/powds</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>

Related

Different resources from context.xml for maven profiles

I have an application running on a tomcat 8 which is working fine. Now I want to build the application for a development, a test and a production environment where the application connects to different database servers and I would like to select which resource to use by a maven property set in the different profiles.
So in my context.xml I have defined my data sources looking like this for each DB server.
<Resource name="jdbc/db-dev" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="user" password="password"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://x.x.x.x:3306/dbname;" />
<Resource name="jdbc/db-test" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="user" password="password"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://x.x.x.x:3306/dbname;" />
And in my web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>${db.context}</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
And in my pom.xml
<profile>
<id>dev</id>
<properties>
<db.context>jdbc/db-dev</db.context>
</properties>
</profile>
And in Java
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup(ENV);
DataSource ds = (DataSource) envContext.lookup("jdbc/db"); // jdbc/db-??? is the issue
return ds.getConnection();
} catch (NamingException e) {
throw new SQLException(e);
}
And there's the problem, in Java I have a fixed string value pointing to only one resource. I know I could create a properties file during build, but for only that one value it seems a little to much. Is there a way to have the resource-ref point to different resources from the context xml while having only one reference name?
Another method I found was to have different resource files which I can include and exclude probably per profile, haven't got into it that much yet but maybe there is a far more easy solution which I just don't see right now.
I would prefer to have the same binaries (i.e. WAR in this case) for every environments in order to follow "Build one, deploy often" CI/CD principle. The environment dependent configurations will then be injected in some ways such as through environment variables ,JVM options when starting the application or external configuration file etc.
From this , Tomcat supports using ${xxxx} for variable substitution in their configuration file :
Tomcat configuration files are formatted as schemaless XML; elements
and attributes are case-sensitive. Apache Ant-style variable
substitution is supported; a system property with the name propname
may be used in a configuration file using the syntax ${propname}. All
system properties are available including those set using the -D
syntax, those automatically made available by the JVM and those
configured in the $CATALINA_BASE/conf/catalina.properties file.
So, context.xml will probably looks likes:
<Resource name="jdbc/db" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="${DB_USER}" password="${DB_PASSWORD}"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://${DB_HOST}/dbname;" />
Then configure ${DB_USER} , ${DB_PASSWORD} and ${DB_HOST} as an environment variables or JVM options when starting tomcat etc....

Tomcat: context.xml and web.xml configs for jndi resource

I have been going over almost all the web.xml/context.xml related questions over the web but nowhere did i get a clear enough answer to my following question.
This says that the resource-ref tag in web.xml is equivalent to Resource tag in context.xml.
This says that resource-ref tag in web.xml looks up the Resource tag in context.xml. Now these two sound confusing specifically because both the links I have referred to are Tomcat doc links and still have seemingly contradictory statements. Any clarifications would be extremely helpful.
The "Resource" tag defines the resource and can be placed in a number of xml files that largely depend upon the deployment preferences. To get started I'd place a context.xml in the META-INF folder in the web app. This directory is at the same level in the web app as the WEB-INF folder an example being:-
META-INF/context.xml
<Context>
<Resource name="jdbc/TestDB" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb"
username="dbuser"
password="dbpassword"
maxTotal="20" maxIdle="10" maxWaitMillis="-1"/>
</Context>
The above makes the resource available.
The resource-ref tag is used to refer to the resource to make it avaiable to your app. This can go in the web.xml file.
WEB-INF/web.xml
<web-app>
<!--- snipped -->
<resource-ref>
<description>Test DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Both of these can be configured in other ways. I usually go with something like this then dabble.

jboss 6.4 ignoring webapp directory structure

we are moving from jboss 5.1 to jboss 6.4 and i have below entries in my xxx.ear/META-INF/application.xml. it seems like jboss 6.4 is not able to identify webapp but when I change this to webapp.war then it is deployed, due to this I need to rename my webapp folder to webapp.war.
With jboss 5.1 it is working fine but jboss 6.4 needs this change, is their any way I can suppress this?
Application scripts needs update to rename webapp to webapp.war every where and I want to avoid it.
Thanks in advance.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://java.sun.com/xml/ns/j2ee" version="1.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
<display-name>Web App</display-name>
<module>
<web>
<web-uri>webapp</web-uri>
<context-root>/app</context-root>
</web>
</module>
</application>

Multiple JBoss Web Application Deployment Descriptor with same resources

I have an ear including several war deployed on jboss as 7.1.1.
Each war have a custom JBoss Web Application Deployment Descriptor (jboss-web.xml) declaring the context-root and several jndi datasources all shared between the different web-apps.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>${app.name}</context-root>
<resource-ref>
<res-ref-name>${datasource}</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/TenantDS</jndi-name>
</resource-ref>
<resource-ref>
<res-ref-name>${shared.datasource}</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/CustomerDS</jndi-name>
</resource-ref>
[...]
</jboss-web>
If I add another war with a jboss-web.xml file declaring only the first datasource (because it's the only one used by this war) then none of remaining war is able to reach the missing datasource anymore.
How a webapp specific deployment descriptor can have such a behavior ? And so, what is wrong in this config ? where should the datasource be declared ?
Do you have declared datasource in web.xml? You have to have it in jboss-web.xml and web.xml in each war application.

Issue with JNDI resource with Tomcat 6 on Linux with WAR file

I'm fairly new to Tomcat and Java web development and am banging my head against a wall with an issue im experiencing.
I have a web application that works fine on my local box (windows xp), I have Tomcat 6 installed with the WAR file deployed to the webapps folder and within the c:/apache-tomcat-6.0.18/conf/Catalina/localhost/ directory i have the "myApp.xml".
The myApp.xml contains the following:
<Context path="/myApp" docBase="/myApp.war" debug="1" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" scope="Shareable" type="javax.sql.DataSource" auth="Container" username="test" password="test" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
Then within my web app i have the following info within my applicationContext file
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/sql-connection</value>
</property>
</bean>
Now i've gone from it all working fine on my local box to deploying it on a Linux box, however when I deploy it on there, with exactly the same setup just tomcat is running from "opt/apache-tomcat-6.0.18". Every time I try to start Tomcat on the box it will unpack the WAR file but wont start it, and gives me the following error whenever i try to start it through the manager:
Error creating bean with name 'myDatasource' defined in file [/opt/apache-tomcat-6.0.18/webapps/myApp/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
Ive tried looking all over the internet for an answer but nothing seems to have the exact same issue, and the names seem to match between the tomcat config file and the web app.
First of all, Tomcat doesn't understand myApp.xml (unless you explicitly points it to it, which I don't know how). Tomcat works based on context, which can be configured for your web application. Tomcat allows only deployment of Web Aplication Archive (WAR) file.
To create a context for your application, create a context.xml (all small caps, case-sensitive) file inside your Web application META-INF folder.
Your reference guide to configuring context can be found on Tomcat 6 Config/Context. You will see that attribute debug is deprecated.
The JNDI Resources HOW-TO for Tomcat 6 is also available.
Once you have created your context.xml inside your META-INF folder, paste the following code (taken from your example) below:
<Context path="/myApp" docBase="/myApp.war" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" type="javax.sql.DataSource" auth="Container" username="test" password="test" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
(By default, Tomcat uses PoolableDataSource for Connection Pooling).
Once you're done, config your <resource-env-ref> in your WEB-INF/web.xml. That will allow you to create Shareable scope. Please refer to the link provided on Tomcat 6 JNDI, HOW-TO.
I hope this helps you.

Categories

Resources