Bluemix Liberty server.xml MySQL data source configuration - java

I have an EJB based application that connects to MySQL database and provides web UI for update operations. It works fine when deployed to local WAS Liberty.
Here is the server.xml configuration for data source.
<library id="MySQLDriverLib">
<file name="${User-defined_JDBC_DRIVER_PATH}/mysql-connector-java-5.1.38-bin.jar"/>
</library>
<dataSource id="DefaultDataSource" type="javax.sql.ConnectionPoolDataSource" transactional="true">
<jdbcDriver libraryRef="MySQLDriverLib"/>
<properties URL="jdbc:mysql://localhost:3306/ic16_lab2434" connectionUrl="jdbc:mysql://localhost:3306/ic16_lab2434" driver="com.mysql.jdbc.Driver" driverClass="com.mysql.jdbc.Driver" metadata="mySQL" password="object00" user="root" userName="root" />
</dataSource>
<variable name="User-defined_JDBC_DRIVER_PATH" value="C:\Software\mysql-connector-java-5.1.38"/>
As you can see, it uses library for JDBC driver jar, which is specified with path to file. Obviously, this won't work if I try to deploy just EAR to Bluemix Liberty. That's why I am deploying whole server directory to make least number of changes. Yet even in this case I don't know how to properly configure JDBC driver library for data source so server picks it up. Please help.

If you want to connect to a mysql database and want to manually provide the credentials in the server.xml, you can do the following:
server.xml:
<dataSource jndiName="jdbc/TradeDataSource">
<jdbcDriver id="mysqlDriver" libraryRef="mysql-connector" />
<properties
URL="jdbc:mysql://1.2.3.4:3306/db"
password="mypassword" user="admin" />
</dataSource>
<library description="MySQL JDBC Driver" id="mysql-connector"
name="MySQL Connector">
<fileset dir="${server.config.dir}" id="mysql-connector-jar"
includes="mysql-connector-java-*.jar" />
</library>
In this example, I would put the mysql jar file in the server config directory wlp/usr/servers/defaultServer/mysql-connector-java-5.1.34-bin.jar
You can now cf push directly from the defaultServer dir
However, the liberty buildpack can automatically generate the server.xml datasource config for databases that you bind from the Bluemix catalog. For example, if I create and bind a SQLDB or ClearDB service to my Liberty application and name the service it "TradeDataSource", the buildpack will generate the config and add the right driver jar to the classpath automatically.
cf files yourappname app/wlp/usr/servers/defaultServer/server.xml
<dataSource id='mysql-TradeDataSource' jdbcDriverRef='mysql-driver' jndiName='jdbc/TradeDataSource' transactional='true' type='javax.sql.ConnectionPoolDataSource'>
<properties id='mysql-TradeDataSource-props' databaseName='${cloud.services.TradeDataSource.connection.name}' user='${cloud.services.TradeDataSource.connection.user}' password='${cloud.services.TradeDataSource.connection.password}' portNumber='${cloud.services.TradeDataSource.connection.port}' serverName='${cloud.services.TradeDataSource.connection.host}'/>
<connectionManager id='mysql-TradeDataSource-conMgr' maxPoolSize='10'/>
</dataSource>
<jdbcDriver id='mysql-driver' javax.sql.XADataSource='org.mariadb.jdbc.MySQLDataSource' javax.sql.ConnectionPoolDataSource='org.mariadb.jdbc.MySQLDataSource' libraryRef='mysql-library'/>
I can now look up the datasource using its jndi name: jdbc/TradeDataSource

Related

configuring dev and prod datasource in liberty dynamically to load based on the environment

I am running java batch(jsr352) using liberty server. The datasource configured in server.xml. I would like to load server.xml based on the region(like dev, sit, prod). How can I pass arguments to start liberty server and load the datasource dynamically
There could be possiblity with server.env file and bootstrap.properties. since new to this.. can anyone help on this.
An easy way to do this is to use variables in your server.xml like this:
<dataSource jndiName="jdbc/db2">
<jdbcDriver libraryRef="DB2JCCLib"/>
<properties.db2.jcc databaseName="${evn.db2_name}"
serverName="${env.db2_server}"
portNumber="${env.db2_port}"/>
</dataSource>
Then, you could can set the variables in your server.env like this:
db2_name=mydb
db2_server=whatever.com
db2_port=50000
Alternatively, if you use any sort of scripting to start your Liberty servers, you can export them in the bash env like this:
$ export db2_name=mydb
$ etc...
$ wlp/bin/server start myServer
If you have configuration differences that go beyond attribute values, variables may not be sufficient. For example, suppose you use an in-memory database in dev (like Derby embedded) and a more robust database in production (like DB2).
In your primary server.xml, you can include another config xml file using a variable like this:
<server>
<include location="dbconfig-${env.ENV_LOCATION}.xml"/>
<!-- rest of common config here -->
</server>
Then you can have dev-only config in dbconfig-dev.xml like this:
<server>
<dataSource id="db" jndiName="jdbc/db">
<jdbcDriver libraryRef="DerbyLib"/>
<properties.derby.embedded databaseName="memory:testdb" createDatabase="create"/>
</dataSource>
<library id="DerbyLib">
<fileset dir="/path/to/derby.jar"/>
</library>
</server>
And production-only config in dbconfig-prod.xml like this:
<server>
<dataSource id="db" jndiName="jdbc/db">
<jdbcDriver libraryRef="DB2JCCLib"/>
<properties.db2.jcc databaseName="PRODUCTION_DB"
serverName="serious.business.com"
portNumber="50000"/>
</dataSource>
<library id="DB2JCCLib">
<fileset dir="/path/to/db2.jar"/>
</library>
</server>
Then, based on which value is set for ENV_LOCATION, either dbconfig-dev.xml or dbconfig-prod.xml will be included in your primary server.xml config.

How does JBoss 7.1.1 manage connection to different schemas of the same database

So I have a servlet where I login to a database with Datasource(where I only pass the JNDI name) with a default schema(which was set in the JBoss management console) but later on I need to connect on the same database with another schema in order to get some texts.
How does JBoss manage this ? Can I provide the later schema and password somehow in the java code ?
În standalone.xml you declare all your datasources. Those connections can be picked up by jndi at runtime by looking up on an InitialContext instance.
When using JNDI to form connections, you will need to configure the new datasource within the management console or the standalone.xml file. This will simply be a new datasource, with a connection URL going to the same database, but pointing to a new schema.
Example output in the standalone.xml:
<datasource jta="false" jndi-name="java:/firstDS" pool-name="firstDS" enabled="true" use-ccm="false">
<connection-url>jdbc:oracle:thin:#devdb:1521:SCHEMA_1</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
...
<datasource jta="false" jndi-name="java:/secondDS" pool-name="secondDS" enabled="true" use-ccm="false">
<connection-url>jdbc:oracle:thin:#devdb:1521:SCHEMA_2</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
Now in the second part of your application you will just refer to that second datasource's JNDI name when forming the connection.

set a data source in jboss standalone mode

I want to set a mysql data source in jboss standalone mode. I have already deploy the mysql-connector-java-5.1.15-bin.jar and set the below data source configuration in standalone.xml under datasources
<datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://localhost:3306/testdb</connection-url>
<driver>mysql</driver>
<security>
<user-name>root</user-name>
</security>
</datasource>
And when i click on the configured data source name in the web console im getting below error,
Internal server error{
"outcome" => "failed",
"failure-description" => "JBAS014739: No handler for read resource at address [
(\"subsystem\"=>"\datasource\"),
(\"data-source\"=>"\MySqlDS\"),
(\"statstics\"=>"\pool\"),
"],
"roleback" => "true"
}
I didnt add any thing to the drivers section since it not nessaccary,
Below one is set to the sample data source set in jboss
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class
</driver>
</drivers>
What i am missing here please?
You will also need to specify driver class
<driver-class>com.mysql.jdbc.Driver</driver-class>
Checkout this link How do I migrate my application from AS5 or AS6 to AS7
I've experienced the same issue under the same circumstances. The problem was that my AS didn't have the required module for PostgreSQL. Check in jboss/modules/org if you have a folder named postgresql. If not then create it. Then create a directory in it named main.
You then have to have two files present in there:
PostgreSQL JDBC JAR
module.xml configuration file
Download the JAR file according to the database you're using and copy it here. As for the module.xml just create a new file and set up the configuration. Mine looks like this, customize it for your case:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.postgresql">
<resources>
<resource-root path="postgresql-9.3-1100.jdbc4.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
Basically you just have to change the resource path to where your JAR file is.
This is an issue with JBOSS, it doesn't warn you even though the JDBC driver is missing. I've wasted a ton of time finding this hidden bug :D

How to set tomcat work at debug mode?

I deploy a application to tomcat with context xml. I want the tomcat work at debug mode, I means if I change something inside a function, like change
String a="123";
to
String a="456";
tomcat should get the change without reload the application.
The web01.xml under %CATALINA_HOME%/conf/Catalina/localhost
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="d:/document/workspace3.6/web01/WebContent" path="/web01" reloadable="false" debug="1" ></Context>
but now tomcat didn't worked as I expected, if I replace the old class file with new version, I must restart tomcat to get the change.
Why tomcat didn't reload the class,How should I do to let it work as debug mode?
I am not use Eclipse now. and I don't want to set reloadable="true", this will reload the entire application if class changed.
I used tomcat5.5.23
You're actually confusing the notions of "debugging" and hot deploy. You can configure Tomcat for debug mode, and then remotely debug your application running inside tomcat such that when you add a break point in your code, the debugger will jump to that breakpoint and halt execution.
What you actually need there is having the possibility to hotdeploy an application. With tomcat, if you modify the .java files and then copy them to the working directory of tomcat, you'll get exactly what you want, namely the ability to change something in a class and have the running tomcat-deployed application take it into account without redeploying the whole application. You can automatize this by configuring your tomcat application context (either in the tomcat server.xml file or in a project specific context.xml file) for your application to have as working directory the directory where your project code gets compiled.
here's an actual example:
Let's say you have a maven project in the directory c:\myProject. You'd have source files in the c:\myProject\src, and then when compiling it you'd get the war file and an exploded directory of the war file content in the c:\myProject\target\myProject.war and respectively c:\myProject\target\myProject. Now, if you configure your tomcat such that for the myProject tomcat context, youd have the working directory configured as c:\myProject\target\myProject, then each time you modify a .java file, the .class corresponding file will be updated in the target (and now also working) dir, and tomcat will take it into account.
I've actually used such a setup to develop with tomcat, but it's not the best. First off tomcat will hotdeploy only certain modifications, such as when you modify something in the body of an existing method. Other modifications will not be taken into account, such as adding a new method - for this you have to do a full redeploy to have it taken into account.
A far better solution is to use maven with the maven jetty plugin. This thing really works as you want: any modification you do to a class of jsp file will me immediately taken into account, and visible in the running app inside jetty.
Ok, here's an actual example:
I have the cnas-war maven project. Once I build it with Maven, I get the following directory:
c:/_andrei/work/cnas/cnas-war/target\cnas-war-0.0.1-SNAPSHOT
In here I have all the stuff that normally would get packaged in the .war file, like .class files, .jsp files, .jar files etc. Effectively it's the .war file exploded.
I also have a Tomcat 5.5 specifically tailored for the deployment of this war, cleverly placed in the tomcat_cnas folder. In the Tomcat config file (conf\server.xml) I have the following:
<?xml version="1.0" encoding="utf-8"?>
<!-- Example Server Configuration File -->
<!-- Note that component elements are nested corresponding to their
parent-child relationships with each other -->
<!-- A "Server" is a singleton element that represents the entire JVM,
which may contain one or more "Service" instances. The Server
listens for a shutdown command on the indicated port.
Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" or "Loggers" at this level.
-->
<Server port="8125" shutdown="SHUTDOWN">
<!-- Comment these entries out to disable JMX MBeans support used for the
administration web application
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/> -->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<!-- Global JNDI resources -->
<GlobalNamingResources>
<!-- Test entry for demonstration purposes -->
<Environment name="simpleValue" type="java.lang.Integer"
value="30" />
<Resource auth="Container"
configurationDirectory="c:/cnas-content"
factory="com.genia.toolbox.web.jndi_config.StringContainerFactory"
name="string/activitymanagerConfigurationContainer"
type="com.genia.toolbox.web.jndi_config.StringContainer" />
<Resource name="string/activitymanagerConfigurationContainer"
auth="Container"
type="com.genia.toolbox.web.jndi_config.StringContainer"
factory="com.genia.toolbox.web.jndi_config.StringContainerFactory"
configurationDirectory="c:/cnas-content" />
</GlobalNamingResources>
<!-- Define the Tomcat Stand-Alone Service -->
<Service name="Catalina">
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector acceptCount="100" connectionTimeout="20000"
disableUploadTimeout="true" enableLookups="false"
maxHttpHeaderSize="8192" maxSpareThreads="75" maxThreads="150"
minSpareThreads="25" port="8081" redirectPort="8443" />
<!-- Define the top level container in our container hierarchy -->
<Engine defaultHost="localhost" name="Catalina">
<!-- for activitymanager -->
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="true" xmlValidation="false"
xmlNamespaceAware="false">
<Context path="/cnas"
docBase="c:/_andrei/work/cnas/cnas-war/target/cnas-war-0.0.1-SNAPSHOT/"
workDir="c:/_andrei/work/cnas/cnas-war/target/work-cnas/">
<ResourceLink name="string/configurationContainer"
global="string/activitymanagerConfigurationContainer"
type="com.genia.toolbox.web.jndi_config.StringContainer" />
<Resource name="bean/cnasConfig" auth="Container"
type="com.genia.toolbox.projects.cnas.war.config.CnasConfig"
factory="org.apache.naming.factory.BeanFactory"
classpath="false" fileSystem="true"
applicationFileLocation="c:/cnas-content/application.properties" />
<Resource name="bean/cnasApplicationData"
auth="Container"
type="com.genia.toolbox.projects.cnas.war.config.CnasConfig"
factory="org.apache.naming.factory.BeanFactory"
classpath="false" fileSystem="true"
applicationFileLocation="c:/cnas-content/cnas_application_data.xml" />
</Context>
<!--Context docBase="C:/travail/workspace/cnas/cnas-ws-proxy/target/webapp" path="/proxy">
<Resource name="bean/params"
auth="Container"
type="fr.genia.cnas.config.Parameters"
factory="org.apache.naming.factory.BeanFactory"
log4jFile=""
serviceUrl=""
debugMode="true" >
</Resource>
</Context-->
</Host>
</Engine>
</Service>
</Server>
As you can see, in the "context" tag I have a docBase property pointing to the snapshot directory (the one where the war is exploded after maven builds it). Now, with this setup, and having this project imported into Eclipse, if I do a maven build, and then start this Tomcat, the war will be deployed and running. At this point, if I modify the content of a method in a .java file inside Eclipse (and save), then that code will be automatically taken into account by Tomcat and the application will behave differently, without any extra re-deployment. Hope this helps
How to configure Tomcat 5.5 for debug mode?
To do what you are trying to do, You would need some thing like java rebel or some thing similar I know there are some open source alternatives to do the same.

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