Maven 2: Make the application management better and easier

I remembered I first know about the name “Maven” in my graduate job two years ago. At that time, the version is still Maven 1, which is very different from the current version, in terms of architecture, management flows and many other constraints. Also, what I thought about Maven is just a dummy thing since we used it to do one task only, which is to copy the necessary jar files from “somewhere” to the my project folder. That’s all.

Now, Maven 2 is out for some time already, and because one open-source project that I participated in uses this to build the project. It interests me to take a try. Before anything, I just search for the plugin on Eclipse, which ultimately I want to put all my development stuff to. There are two plugins currently supported according to the Maven site (http://maven.apache.org/eclipse-plugin.html). I just tried the first one, M2. It is a very simple tool which helps you to create the basic and core pom.xml file, importing those dependencies inside by searching a jar database.

Next, of course I need to setup the Maven 2 libraries and a local repository by installing the Maven program. This is simple and I will skip. Maven 2 has a clear infrastructure that everyone should follow, this not only easy to set everything up, but also enables a good management model. Whenever a Maven user views your project, he will be able to understand the structure of your project.

To setup the project, you should put your class files, webapp files and resources etc. in appropriate folder structure. Whenever you run the mvn command, it will go to those pre-defined folder to retrieve the contents and do the required goals.

Besides, for those who used to use Tomcat Plugin in Eclipse to run the hot code, you may find the new structure not suitable. For me, I used to put things WEB-INF folder under the root, with all the necessary web application structure set inside. The source could reside in WEB-INF/classes folder, or put somewhere like src. The only difference is the source folder in Java Build Path. After that, in the properties of the project, tick the “Is a Tomcat Project” box. Then, the project is included in the tomcat instance.

This works because you can control the project structure as you want. However, Maven 2 is the tool which wants to comes up a general file structure among all Maven 2 projects. Thus, conflicts happen, we cannot use tomcat plugin simply after switching to Maven 2. We need some tricks.

Figure 1

maven_1.jpg

Figure 2

maven_2.jpg

Maven 2 with Tomcat Plugin

In order to work, we can do the followings after creating the Maven 2 project.

  1. In Figure 3, change the source folder to the new Maven 2 compatible source folders, including usual classes and test classes (if available)
  2. Change the Default output folder to {your-project}/target/{warName}/WEB-INF/classes
  3. In Figure 4, change the Subdirectory to set as application root to /target/{warName}
  4. (Optional)

Why I did those steps? You know, target is the folder that Maven 2 put the compiled classes and resources by default before it package the war file. What I did is to send all the compiled things to one place and let Tomcat to read those. By doing this, you can still modify your hot code and run on-the-fly, instead of packaging the war file and copy to the container each time even you add a variable to a class.

Defect

  • One main defect for this approach is that files lie in src/main/webapp cannot be reflected upon editing, since they are not automatically replicated to the target folder.

Solution

  • Firstly, I will put all the concurrently modifying JSP files into src/main/java as well, these files will be “compiled” and put to the classes folder. With the use of struts in my projects, I redirect the requests to JSP within classes. (This also protects your JSP files from being accessed outside)
  • Secondly, for the remaining files like javascript, styles, images, etc. I will reside them in src/main/webapp. Each time I changed, I need to run mvn package to let them replicated to the target folder. This action will not bother Tomcat. That means to some extent, it is still play on-the-fly.

Figure 3

maven_3.jpg

Figure 4

maven_4.jpg

References: 

http://spatula.net/blog/2007/04/how-to-make-eclipse-tomcat-maven-2-and.html

JPA 101 Java Persistence Explained

Just found a book introduction from TheServerSide.com

This book explains the concept of JPA, with some useful knowledge on the persistence standard, JPA Annotations, Entity Manager and JPA Query Language (also known as EJB-QL), etc. There are examples, and a simple Maven 2 application with MySQL Database, and Hibernate as the persistence provider will be build after reading through the book. I hope this will be useful for my development using JPA.

Post on TheServerSide
JPA101 Chapter
Author: Chris Maki’s Blog
http://jroller.com/page/cmaki

Import Excel data into MySQL

I want to import data in an Excel file into MySQL table. MySQL tools like MySQL Query Browser does not provide such function. There are sharewares on the web which provide this function. Instead, you can use function that already provided by MySQL, easy and quick solution.

First, you need to export the data to csv file. Remove any csv headers from the file. After that, run the following script in MySQL Console:

load data local infile 'uniq.csv' into table tblUniq
fields terminated by ','
enclosed by '"'
lines terminated by '\r\n'
(uniqName, uniqCity, uniqComments)

This script loads the file uniq.csv from the local file directory, and imports to table tblUniq. It tokenized the field by terminator, and enclosed all fields with specified character.

In using this script, you need to take care of the special characters in the fields. When exporting csv, if one of the fields got a comma, this field will be enclosed by ” as well. It will cause conflict with the above script. So, to solve this, put your csv file into a Text editor and do some customization before using the script. For example, use “|” instead of “,” for the terminator, etc.

Reference:

http://www.thejackol.com/2005/02/28/import-excelcsv-into-mysql/#comment-50169

Install CA-signed Certificate

These days I have a very good experience on installing a CA-signed certificate to our Faculty server. I found that it is much more complicated than a self-signed certificate that I used before. There are lots of formats, types and others things that arouse my concerns during the installation. Let’s walk through some of these.

Before my work, the Faculty of mine bought a certificate from a CA named GeoTrust (which also refers to Equifax). The certificate from this CA has already been installed in more than 90% browsers nowadays, so it is quite a common one compared with those like Verisign and Thawte. That certificate bought is used on one Apache HTTP Server, and my work is to install it to Apache Tomcat on the same machine.

For the usage in Apache HTTP Server, there are two files, which are named like mycert.crt and mykey.key. These two files are the public key and private key respectively. I don’t know what format they are, but I can’t use either of them as the keystore provided to tomcat. Tomcat will throw javax.net.ssl.SSLException and saying that: No available certificate or key crresponds to the SSL cipher suites which are enabled.

After that, I sent an email to the support and asked for help. The guy there provide me a way to go, which is to convert the certificate to the format that Tomcat can use. The procedure is like this:

1. Run the following command to create a keystore named “mycert.p12″ with an alias “tomcat” inside (The alias must be “tomcat”, as it is recognized by Apache Tomcat)

openssl pkcs12 -export -in mycert.crt -inkey mykey.key -out mycert.p12 -name tomcat -CAfile GeoTrustRootCA.cer -caname root -chain

Where GeoTrustRootCA.cer’ is the GeoTrust Root CA available for download here: http://www.geocerts.com/support/roots.php , ‘mycert.crt’ is your current ssl certificate, ‘mykey.key’ is your current private key.

For the GeoTrust Root CA, either Base-64 and DER format can be used. There is no difference after all the works.

2. After running the command, it will ask you for the password, typed in “changeit”. Oh, why “changeit”? Actually, the password is up to you, but it is used by Tomcat to access this keystore. If you used other password, you have to explicitly provided in the Tomcat configuration, which we will talk in Step 4.

3. The keystore named “mycert.p12″ is created, it is a X.509 certificate with PKCS#12 format. The format is different from the self-signed certificate created by “keytool”, which is JKS (Java KeyStore)

4. Configure the Tomcat server to switch on secure connection as usual with some additional settings as below:

You then have to specify Tomcat that the keystore is in pkcs12 format by inserting keystoreType=”pkcs12″ in the ssl configuration, also the keystore location pointing to where mycert.p12 is located.

After configuring this, the SSL should be ready using this CA-signed certificate.

Remarks:

There are still some questions that I didn’t solve, which are all related to the command used in Step 1. Some of the options like “-caname” and “-chain” are still unknown to me. Perhaps, someone can give me an answer.

Reference:

http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html
http://www.geocerts.com/support/install/install_tomcat.php

Changes in XML Schema for web.xml

One of the major change for this 2.4 version of web.xml is the ordering of tags. As the use of XML Schema provides the flexibility on the ordering of tags, you can put the tag in any ordering as you like.

Besides this, one another change is the use of tag library. Starting from 2.4, we have to surround all <taglib> with a new tag <jsp-config>, as required by the mechanism of XML Schema, like the following:

<web-app xmlns=”http://java.sun.com/xml/ns/j2ee&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&#8221;
version=”2.4″>

<description>StrutsTest</description>

<jsp-config>

<taglib>
<taglib-uri>http://jakarta.apache.org/tomcat/debug-taglib</taglib-uri&gt;
<taglib-location>/WEB-INF/jsp/debug-taglib.tld</taglib-location>
</taglib>

</jsp-config>

</web-app>

Learning EJB-QL

Seems that there is still not much resource on Java Persistence, which is included in EJB3. If I want to learn more about EJB-QL, the only way is to look at the resources of EJB2.1. The articles may not be updated, but most of the contents still apply.

However, I found one EJB-QL that is in the spec. seems not supported by most of the vendors, which is OFFSET and LIMIT. I found some articles on people asking Sun about the issue, but no one answers. Then I do a search on Google, and only found Resin which supports it.

These keywords are used together to limit the number of entity instances returned in a list, especially useful for entity storing up to ten thousand records. Your memory size must be a main issue by then. Actually, it is just similar to the ROWNUM functions provided by Oracle, but don’t know why so few vendors implement such a useful function.

MySQL problem again

When I am thinking using autoReconnect will resolve the disconnection problem, a new error comes to me.

java.net.SocketException
MESSAGE: Software caused connection abort: recv failed

This error appears in occasional case, but also after a long hours of idle. I used Java Persistence to connect mysql. Today morning, when I was back to office. My application seems fine when doing the querying functionalities. However, when I used persist() and merge() operations which updated the DB, this error occurred.

Someone said this also the same problem as previous, which MySQL disconnects the connections after idle for 8 hours, but I am amazing that the error only throw for updating operations. Is it mechanism for Java Persistence, since it can store part of DB details in memory, so it didn’t actually query the database?

Reference:
http://forums.mysql.com/read.php?39,55337,95721#msg-95721

Exception: socket write error

These days, this exception always occur in my new developing application using persistence, especially on the morning when I came back to office. At the beginning, I think it may be due to the use of Java Persistence. However, when I do a search on Google, at the top of the list, I got this post:

http://www.yannicafe.info/wp/2006/11/25/53.html

This post describes the case in detail. It is due to the mechanism of MySQL, where this DB will disconnect all the active connections after 8 hours if there is no activity. After that, if your application try to work on some activities, the above exception is caused.

Normally, the exception should be caught in the application, and direct to a reconnect logic. However, the persistence provider (Oracle TopLink) that I am using does not provide auto reconnect function. So, I need to change the connection URL to the following:

jdbc:mysql://localhost:3306/test?autoReconnect=true

This allow the application to auto reconnect in case MySQL disconnects all the connections. Nevertheless, the bad thing is that  this is not recommended by MySQL community and this parameter may even be removed from future versions of MySQL.

Reference:
http://forums.java.net/jive/thread.jspa?messageID=189962

关注

每发布一篇新博文的同时向您的邮箱发送备份。