When attempting to make a build in Hudson for the first time, it complained of missing artifacts in the maven repo. I found that I had to configure the MAVEN_HOME/conf/settings.xml file to point to the maven repo by editing the localRepository element
Here's a reference for more details:
http://stackoverflow.com/questions/44144/hudson-cant-build-my-maven-2-project-because-it-says-artifacts-are-missing-from
Once the initial build was working, I had to make additional changes to make maven do a 'clean package'
and perform a build everytime a change gets submitted to SVN as shown below:
Tips and experience about developing websites with various technologies
Wednesday, April 28, 2010
Tuesday, April 27, 2010
SFTP: Received message too long 1936094320
The problem:
Recently the server running SFTP was updated with some security patches applied. Soon afterwards, one of the users couldn't connect via SFTP with the following error:
Recently the server running SFTP was updated with some security patches applied. Soon afterwards, one of the users couldn't connect via SFTP with the following error:
$ sftp broken_user@server
Received message too long 1936094320
I spent quite a bit of time searching for solutions and most talked about an echo statement in one of the .bashrc or .bash_profile scripts. However, upon inspection I couldn't find any echo statements.
However, I noticed that when I used the root user it worked fine:
$ sftp root@server
The solution:
I did manage to find a workaround, although I am still unable to explain why it works.
I ended up editing the /etc/passwd file and changed a line from:
broken_user:x:503:503::/var/websites/my_website/./:/bin/sftpsh
to
broken_user:x:503:503::/var/websites/my_website/./:/bin/bash
Thursday, April 8, 2010
Extending an existing Web application WAR
Problem:
Extend an existing web application, reusing as much as possible including not just the source code, but the web resources such as JSPs, images, CSS styling, Javascript etc...
The simple way would be to branch or copy the existing application and import it into a new project, but this has a major drawback. What if there are bug fixes or changes made to the base web application? If we were to branch, then that would mean having to merge all the changes from the base web application with the new web application! I say GAH!
Solution:
If you're already using Maven as your build, then it's Maven WAR overlays to the rescue!
An article about Maven WAR overlays can be found here:
Reference: http://maven.apache.org/plugins/maven-war-plugin/examples/war-overlay.html
To automatically include all dependencies from the base WAR, I use the warpath plugin found here:
http://static.appfuse.org/maven-warpath-plugin/usage.html
You are effectively creating a WAR project that has a dependency on the base WAR project found in your maven repo. Thus, any changes made to the base WAR application can easily be picked up by simply synching up with your SVN code base and rebuilding your new WAR.
In your new web app project, when you make a build, maven will automatically merge the 2 WAR files (base WAR and new app WAR) together to create a new WAR file.
Below is a sample of the pom.xml file to enable this merging:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>au.org.australianphenomics</groupId>
<artifactId>podd-apn-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>podd-apn-webapp</name>
<url>http://maven.apache.org</url>
<developers>
<developer>
<name>Philip Wu</name>
<email>philip.wu@anu.edu.au</email>
</developer>
</developers>
<!-- ================
Build
==================== -->
<build>
<finalName>podd-apn</finalName>
<plugins>
<plugin>
<groupId>org.appfuse</groupId>
<artifactId>maven-warpath-plugin</artifactId>
<version>2.0.2</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>add-classes</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<dependentWarIncludes>**</dependentWarIncludes>
</configuration>
</plugin>
</plugins>
</build>
<!-- ================
Dependencies
==================== -->
<dependencies>
<dependency>
<groupId>au.edu.uq.itee.maenad</groupId>
<artifactId>podd-webapp</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>au.edu.uq.itee.maenad</groupId>
<artifactId>podd-webapp</artifactId>
<version>1.0</version>
<type>warpath</type>
</dependency>
</dependencies>
</project>As an 'Overlay' the web.xml files from the two WARs are not merged.
If you're looking to do just that, then you might want to take a look at:
http://cargo.codehaus.org/Merging+WAR+files
Monday, April 5, 2010
Java String.trim() not trimming Whitespace!
The problem:
I was using String.trim() to remove leading and trailing whitespace characters from an imported string.
However it turns out, that the trim() method only checks for a whitespace characters defined in ASCII.
That is, any non-ASCII whitespace characters will still persist!
Reference: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4080617
Upon inspecting each character of the string, the whitespace character returned a value of 160
The code to inspect is below:
The solution was to remove all instances of this troublesome character with the following code:
I was using String.trim() to remove leading and trailing whitespace characters from an imported string.
However it turns out, that the trim() method only checks for a whitespace characters defined in ASCII.
That is, any non-ASCII whitespace characters will still persist!
Reference: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4080617
Diagnosis:
Upon inspecting each character of the string, the whitespace character returned a value of 160
The code to inspect is below:
for (int i=0; i < string160.length(); i++) {
char c = string160.charAt(i);
int intC = (int) c;
System.out.println(intC);
}
Solution:
The solution was to remove all instances of this troublesome character with the following code:
string160 = string160.replaceAll("[\\u00A0]", "");
Thursday, March 25, 2010
Constructing table views with Hibernate
Database views are convenient to use especially for a view that represents a complex query or one that is used repetitively.
Here I will show you how to construct a database view using Hibernate.
In the HBM mapping file you can declare your view using the element subselect.
The SQL used should be native to the database you are using and should not be HQL.
You use the synchronize elements to identify which tables the SQL query uses to construct the view.
Below is an example:
I combine two foreign key ID's to construct a unique key for the table view as follows:
The entity representing the view is a simple POJO as follows:
Here I will show you how to construct a database view using Hibernate.
In the HBM mapping file you can declare your view using the element subselect.
The SQL used should be native to the database you are using and should not be HQL.
You use the synchronize elements to identify which tables the SQL query uses to construct the view.
Below is an example:
<!-- VIEW -->
<class name="au.edu.apf.phenomebank.report.inventory.mouse.StrainCryo" >
<!-- Postgres specific SQL call -->
<subselect>
SELECT '' || cs.id || s.id AS id, s.id AS strain_id, cs.id AS cryosession_id
FROM cryo_session cs
JOIN cryo_session_result csr ON(cs.id=csr.cryo_session_id)
JOIN mouse m ON (csr.mouse_id=m.id)
JOIN strains s ON (m.strain_id=s.id)
GROUP BY cs.date_of_session, s.id, cs.id
ORDER BY cs.date_of_session
</subselect>
<synchronize table="cryo_session"/>
<synchronize table="cryo_session_result"/>
<synchronize table="mouse"/>
<synchronize table="strains"/>
<id name="id" type="java.lang.Long" />
<many-to-one name="strain" column="strain_id" cascade="none" not-null="true" />
<many-to-one name="cryoSession" column="cryosession_id" cascade="none" not-null="true" />
</class>I combine two foreign key ID's to construct a unique key for the table view as follows:
'' || cs.id || s.idThe entity representing the view is a simple POJO as follows:
public class StrainCryo {
/**
* Arbitrary ID to create the view in Hibernate
*/
private Long id;
private Strain strain;
private CryoSession cryoSession;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Strain getStrain() {
return strain;
}
public void setStrain(Strain strain) {
this.strain = strain;
}
public CryoSession getCryoSession() {
return cryoSession;
}
public void setCryoSession(CryoSession cryoSession) {
this.cryoSession = cryoSession;
}
}
Monday, March 15, 2010
Externalizing configuration properties
Generally, for deployment specific configurations we would like to move them out of spring specific configuration files and into a properties file.The purpose of the bean-wiring file is to define the relationships between dependent objects, and should not be used to define deployment configurations.
I've come across 2 ways to Externalize configuration properties and it really depends on the technologies you have at your disposal.
Preferrably, I like to use the Maven Resource filtering strategy, because it allows you to easily create a different build depending on the type of deployment you'd like to use based on Maven Profiles. Here's a good quote describing Maven resource filtering:
I've come across 2 ways to Externalize configuration properties and it really depends on the technologies you have at your disposal.
- Using Spring's PropertyPlaceholderConfigurer: More details
- Using Maven's Resource filtering: More details
Preferrably, I like to use the Maven Resource filtering strategy, because it allows you to easily create a different build depending on the type of deployment you'd like to use based on Maven Profiles. Here's a good quote describing Maven resource filtering:
You can use Maven to perform variable replacement on project resources. When resource filtering is activated, Maven will scan resources for references to Maven property references surrounded by${and}. When it finds these references it will replace them with the appropriate value in much the same way the properties defined in the previous section can be referenced from a POM. This feature is especially helpful when you need to parameterize a build with different configuration values depending on the target deployment platform.
Sunday, February 14, 2010
Why isn't my datasource configuration being picked up in Tomcat 6?
I had an unusual problem with Tomcat 6 where changes to my database configuration stored in the /META-INF/context.xml file was not being picked up upon server restart or application reload.
Below is a sample:
When I had changed the database name from 'phenomebank' to something else like 'newdatabase', the log files continued to show that it was trying to connect to 'phenomebank' instead of 'newdatabase'
It turns out that Tomcat 6 was caching my configuration file in a separate directory, such that application reload and server restart would not automatically pick up the new configuration!!
The solution was to delete the cached files in Tomcat 6 found in this folder:
To prevent Tomcat from caching the configuration again you can edit an attribute called cachingAllowed in your context.xml as follows:
Below is a sample:
<!-- antiResourceLocking="true" -->
<Context path="/phenbank"
reloadable="true"
>
<Resource name="jdbc/phenomebank"
type="javax.sql.DataSource" username="" password=""
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/phenomebank"
maxActive="8" maxIdle="4"
global="jdbc/phenomebank"
/>
</Context>When I had changed the database name from 'phenomebank' to something else like 'newdatabase', the log files continued to show that it was trying to connect to 'phenomebank' instead of 'newdatabase'
It turns out that Tomcat 6 was caching my configuration file in a separate directory, such that application reload and server restart would not automatically pick up the new configuration!!
The solution was to delete the cached files in Tomcat 6 found in this folder:
C:\apache-tomcat-6.0.20\conf\Catalina
To prevent Tomcat from caching the configuration again you can edit an attribute called cachingAllowed in your context.xml as follows:
<Context path="/zebrafish"
reloadable="true"
cachingAllowed="false" >
Subscribe to:
Posts (Atom)
