Java DB connections in the real world

Yes I’m muttering about relational database connections AGAIN (prepared to be bored to within an inch of your life), and why you ask, because as a domino person who now makes most of his money from none domino projects, as is my current team leader, we are used to database connections being something you just ask for and then forget, they are always there, they don’t time out and they handle them selves quite beautifully, not like the java lot, for all you “domino is old and naff” lot, i’ll take you on with database connection any day of the bloody week, anyway enough ranting.

Technologies used/supported:

Jboss 4.0.5,
MYSQL 5,
hibernate 3.2
C3p0 1.7.2
Java 1.6

These kind of issues (including the Quartz based one I’m doing an article on later), all come about because we are trying to do things properly, and by properly i mean the same .War file works the same all the way from dev to Live, because it gets its connection info from con-fig documents on the server/db rather than hard coded into the app

Soooo

Now your all used to seeing a persistence.xml or hibernate.cfg.xml file that has stuff in it like this

<property name=”dialect” value=”org.hibernate.dialect.MySQLDialect” />
<property name=”hibernate.connection.driver_class” value=”com.mysql.jdbc.Driver” />
<property name=”hibernate.connection.url” value=”jdbc:mysql://127.0.0.1:3306/SETTINGS” />
<property name=”hibernate.connection.username” value=”root” />
<property name=”hibernate.connection.password” value=”rootpassword” />

(if you not, then tell me in the comments and Ill do an “from basics” blog)

All well and good and fine for dev and such, but not what you want in your actual distribution, what you want is something that just says “can i have the ‘setting db’ please”, and for that you need a ‘data source’, so swap out all the database specific lines for the following

<jta-data-source>java:/MYDATASOURCE-DS</jta-data-source>

Then create an xml file (mines called “data-source.xml” in your deployments directory, in my servers case “d:jboss4.0.5serverdefaultdeploy”, and put the following in, filling in the correct gaps

<?xml version=”1.0″ encoding=”UTF-8″?>
<datasources>
<local-tx-datasource>
<jndi-name>MYDATASOURCE-DS</jndi-name>
<connection-url>jdbc:mysql://127.0.0.1:3306/SETTINGS</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>rootpassword</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>

You will need to put the appropriate driver *.jar file in the lib directory of your server (rather than in your app deployment .war file), in my case “d:jboss4.0.5serverdefaultlib mysql-connector-java-5.1.7-bin.jar”, restart your server and ta-da!, you suddenly have a server level data source.

Now in a sane world this should be all you need, but “i don’t think we are in Domino any more toto”, we are in the land of java, you will get lots of weird things happening from time to time but if you are using MYSQL the first one you will encounter is MYSQLs default timeout period of 8 hours, i.e. if you don’t do something every 8 hours the server will chuck you off and refuse to let you back on, unless you redo your whole connection, which in the case of a data source means a server reboot, ARSE!, one solution is to extent the timeout to the max you could want, but that stinks as a solution, a better solutions is to introduce connection pools, which means we introduce yet another layer of abstraction, this one designed to maintain control of the load a application puts on its server and to ensure those connections are available to the application, we will be using c3p0, not only is it the most popular one but its also has the daftest name (we are a star trek house).

First thing is to download c3p0 (it does come with hibernate but for purposes of instructions we will do it from scratch) from http://sourceforge.net/projects/c3p0/ and copy c3p0-x.x.x.x.jar to the same lib directory as you put your database driver, next you need to REPLACE the existing data source file with a new xml file (my new one is called “data-service.xml”) containing the below:

<?xml version=”1.0″ encoding=”UTF-8″?>
<server>
<mbean code=”com.mchange.v2.c3p0.jboss.C3P0PooledDataSource”
name=”jboss.jca:service=DataSourceBinding,name=MYSQL-DS”>
<attribute name=”JndiName”>java:MYDATASOURCE-DS</attribute>
<attribute name=”JdbcUrl”>
jdbc:mysql://127.0.0.1:3306/SETTINGS
</attribute>
<attribute name=”DriverClass”>com.mysql.jdbc.Driver</attribute>
<attribute name=”User”>root</attribute>
<attribute name=”Password”>rootpassword</attribute>
<!– <attribute name=”AcquireIncrement”>3</attribute> –>
<!– <attribute name=”AcquireRetryAttempts”>30</attribute> –>
<!– <attribute name=”AcquireRetryDelay”>1000</attribute> –>
<!– <attribute name=”AutoCommitOnClose”>false</attribute> –>
<!– <attribute name=”AutomaticTestTable”></attribute> –>
<!– <attribute name=”BreakAfterAcquireFailure”>false</attribute> –>
<!– <attribute name=”CheckoutTimeout”>0</attribute> –>
<!– <attribute name=”ConnectionTesterClassName”>0</attribute> –>
<!– <attribute name=”Description”>A pooled c3p0 DataSource</attribute> –>
<!– <attribute name=”FactoryClassLocation”></attribute> –>
<!– <attribute name=”ForceIgnoreUnresolvedTransactions”>true</attribute> –>
<attribute name=”IdleConnectionTestPeriod”>300</attribute>
<!– <attribute name=”InitialPoolSize”>3</attribute> –>
<attribute name=”MaxIdleTime”>600</attribute>
<!– <attribute name=”MaxPoolSize”>15</attribute> –>
<!– <attribute name=”MaxStatements”>0</attribute> –>
<!– <attribute name=”MaxStatementsPerConnection”>0</attribute> –>
<!– <attribute name=”MinPoolSize”>0</attribute> –>
<!– <attribute name=”NumHelperThreads”>3</attribute> –>
<!– <attribute name=”PreferredTestQuery”></attribute> –>
<!– <attribute name=”TestConnectionOnCheckin”>false</attribute> –>
<!– <attribute name=”TestConnectionOnCheckout”>false</attribute> –>
<!– <attribute name=”UsesTraditionalReflectiveProxies”>false</attribute> –>
<depends>jboss:service=Naming</depends>
</mbean>
</server>

The reason you replace the xml file, is that you will most likely be using the same data source name, and they have to be unique to the server, as you can see i have put all of the possible attribute names in the example as they are not documented very well and it was a bugger to find them, but commented them out, you should only really need “MaxIdleTime” and “IdleConnectionTestPeriod”, make sure its set to less than 8 hours (or what ever your db server timeout is), now things should just work after a restart, but you will get a bit more ‘static’ on your console, as c3p0 chatters a bit to the console,

there you go another riveting read, yell if bits are unclear

Client webservice timeout on CXF webservice on Jboss

What a riveting blog title, but this one is mainly for people to find for a solution via google.

Problem: you have a JBoss server with a webservice CLIENT talking to a webservice somewhere else, and you keep getting timeouts, most likely with the following error

org.apache.cxf.phase.PhaseInterceptorChain doIntercept 
INFO: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
        at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226)

If this happens after 60 second (the CXF default timeout), then it is most likely not the target server refusing you, but your client timing out (if your luckily you can get to the target server logs and confirm). Sooo lets extend the client timeout period, personally i like doing this via server configs and indeed that was my first port of call (do a google search for CXF.xml for more details), however even after i figured out what to call the file (cxf.xml, jbossws-cxf.xml, or jboss-cxf.xml) and got it in the right place (inside the WEB-INF of the project for access via POJO’s) the darn thing just ignored me, incidentally the following is the “meat” of the file which should change the timeout (in fact the “*.http-conduit” changes the timeouts on all webservice clients on that app.

<http-conf:conduit name="*.http-conduit"> 
<http-conf:client ConnectionTimeout="120000" /> 
</http-conf:conduit> 

After a prolonged swear, and discovery that i was not the only person who had had this problem on JBoss for CFX clients, I binned that and went into the code, now if your getting this problem then your all ready making a web service client call so you will already have a line like this

Service client = service.yourwebservice();

if you cant find one, and make all you “client stubs” with something like WSDL2Java or via your IDE, do a search for “extends Service”, you are now looking for a line like this

public class myfunkyservice_Service extends Service { 

when you find it, it will tell you what you should go back and look for ie

funkyservice = new myfunkyservice_Service(URL);
myfunkyservice_Service client = funkyservice.yourwebservice();

well something like that anyway, now bung the following code in after it (changing ‘myfunkyservice_Service’ to what ever you client service is called, and not forgetting that the timeout is in milliseconds)

Client cl = ClientProxy.getClient(myfunkyservice_Service);
HTTPConduit http = (HTTPConduit) cl.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(120000);
httpClientPolicy.setReceiveTimeout(120000);
http.setClient(httpClientPolicy);

that’s the code done, it should all work swimmingly, one exception to this is if you get the error

java.lang.ClassCastException: com.sun.xml.ws.client.sei.SEIStub
at org.apache.cxf.frontend.ClientProxy.getClient(ClientProxy.java:93)

What this bundle of joy means is that sun’s library is loading with a higher priority that the CFX lib, if this is on a server its time to get dirty with your config, if this is on your IDE then, go to your projects properties –> Java build path –> Order and export, and bump the CXF lib up (try it at the top)

there you go, now wasn’t that fun 🙂
Old Comments
————
##### Nancy(15/11/2011 20:01:02 GMT)
Thank you very very VERY MUUUUUUUCHH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Really
##### Mark Myers(16/11/2011 19:58:48 GMT)
@Nancy your welcome, glad it helped
##### Mark Myers(27/11/2011 21:48:18 GMT)
@Anneta no prob
##### lucky7175(20/12/2011 06:27:43 GMT)
It works this way

webClient = WebClient.create(URI);
HTTPConduit conduit = WebClient.getConfig(webClient).getHttpConduit();
conduit.getClient().setConnectionTimeout(120000);
##### lucky7175(20/12/2011 06:08:44 GMT)
I dont have control on server code and we use cxf webclient. Can u Pls. let me know how i can set only in client side
##### Mark Myers(22/12/2011 14:42:50 GMT)
yup thank you luckly, isn’t that snippet of code already in the blog at the bottom?

Making any ISO

While building a new win7 VM, I discovered that some of my software was still on DVD/CD only (the horror), I figured that there must be a easy linux way of making an iso image, and diddle me so there is, its called dd The ultimate frenzy guide to how to use this amazing command can be found at How To Do Everything With DD but for me it boiled down to

dd if=/dev/scd0 of=DVDBACKUP.iso

you just need to know where your dvd drive is mounted

$ mount

/dev/sda1 on / type ext3 (rw,noatime,errors=remount-ro)
/dev/sda3 on /home type ext3 (rw,noatime)
/dev/sda1 on /media/SecondHDD type ext3 (rw)
/dev/scd0 on /media/cdrom0 type udf (ro,nosuid,nodev,user=myers) <– This One looks Right

Sooo

myers@EX-L1:~$ sudo dd if=/dev/scd0 of=DVDBACKUP.iso

7816384+0 records in
7816384+0 records out
4001988608 bytes (4.0 GB) copied, 312.694 s, 12.8 MB/s

Cooooor, instant .iso or any order disk copy you might like (its built into all good OS’s, and by that i mean all with a Unix core { yes yes the turtle neck fruit boys can even be included on this one})

Sticky Footers in domino

Any of you who have tried to do sticky footers with domino, may have ground
your teeth in frustration as the best CSS only solutions don’t seem to work,
how ever this one does!!! http://www.cssstickyfooter.com/, well initially it
does not, but in the best tradition of RTFM, all you have to do is look at the
tiny foot note at the bottom of the instructions which is aimed at .Net
developers

"When coding sites for ASP.net where each page is inside a <form> tag, be sure 
to add the form tag to the height:100% statement, else it will break the sticky 
footer. Like this;
html, body, form, #wrap {height: 100%;}"

 

Ohhhhh domino does those as well, and one line of css later, it all works

Multiple JBoss instances step by step

So you have got JBoss working on your linux box, if you did it manually then it
was a long hard fight involving start up scripts and file permission’s, but its
not enough, you want more, maybe you want to try out clustering, maybe you want
a dev and a live instance but only have one box, who knows, who cares, you just
want it, so step by step here it is:

“JBoss” = is the both the name of the existing instance and the user its
installed under (as per JBoss defaults)
“jbossXXX” = the name of the new instance and user
“Jboss-4.0.5.GA” = the JBoss install directory

0) I’m assuming you have already added your multiple IP addresses if not go
here if you are doing it with only 1 IP address and different ports then go
away as i don’t like you anymore, also you should be running in text only mode
for efficiency, if your running a gui then shame on you, and finally you should
be logged on as root or have equivalent rights

1) useradd jbossXXX
(this will create your user and their home directory)

2) passwd jbossXXX
(then enter the new password at the prompt, if you don’t do this the user wont
be activated)

2) passwd jbossXXX
(then enter the new password at the prompt, if you don’t do this the user wont
be activated)

3) mkdir /home/jbossXXX/jboss-4.0.5.GA
(time to make some where for JBoss to live)

4) cp -r /home/jboss/jboss-4.0.5.GA/* /home/jbossXXX/jboss-4.0.5.GA
(clone the current one to a new home)

5) sudo chown -R jbossXXX:root /home/jbossXXX/jboss-4.0.5.GA
(we cloned the file rights as well so lets reset the owner to the user we just
created)

6) cp /etc/rc.d/init.d/jboss /etc/rc.d/init.d/jbossXXX
(make a copy of the existing startup script for the new instance of the server)

7) vi /etc/rc.d/init.d/jbossXXX
(edit it so we change make some changes)

8) press “I” to enter interactive mode
(bloody VI does not start in edit mode)

9) find the following lines and amend with the new server location/user

JBOSS_HOME=${JBOSS_HOME:-“/home/jbossXXX/jboss-4.0.5.GA”}
JBOSS_USER=${JBOSS_USER:-“jbossXXX”}

10) put the new notes ip address in this line

JBOSS_HOST=${JBOSS_HOST:-“192.168.0.10”}

11) Press “escape” to edit interactive mode

12) press ‘shift’+zz to save and exit

13) now normally if you have only one JBoss server, its bound to all available
IP address i.e. the same JBoss server responds to all the IP address you have
on the server, but you cant have that any more so you will have to go into the
“/etc/rc.d/init.d/jboss” and change the line

JBOSS_HOST=${JBOSS_HOST:-“0.0.0.0”}

to be the servers original IP address.

14) run the following

ln -s /etc/rc.d/init.d/jbossXXX /etc/rc3.d/S84jbossXX

ln -s /etc/rc.d/init.d/jbossXXX /etc/rc4.d/S84jbossXXX

ln -s /etc/rc.d/init.d/jbossXXX /etc/rc5.d/S84jbossXXX

ln -s /etc/rc.d/init.d/jbossXXX /etc/rc6.d/K15jbossXXX

ln -s /etc/rc.d/init.d/jbossXXX /etc/rc0.d/K15jbossXXX

ln -s /etc/rc.d/init.d/jbossXX /etc/rc1.d/K15jbossXX

(this makes links from your startup script to all the different ways that you
can start a server up (you really only need mode 3 (multi user text) and mode 6
(multi user gui), but I’m trying to be neat here.

15) bounce the box (yes yes i know you don’t have to do that, but i like to
prove that servers can cope after a power outage) reboot

and that should be your lot

Update
Now it has come to light that old versions of JBoss (seems to be below version
4.2), have a slight bug in that startup and shut down script that still putts
“localhost” as a parameter, even if you have specified an alternative IP
address, as we no longer have one server on the localhost IP address this
obviously breaks things, so while you can start up JBoss with

/etc/init.d/jbossXXX start

to shut it down (individually), you need to use something like

/home/jbossXXX/jboss-4.0.5.GA/bin/shutdown.sh -s jnp://192.168.0.10:1099

End Update