woensdag 19 december 2007

Java multiple inheritance

shown by example:

We need multiple inheritance when developing the Web client that talks to the message server. Our Web client is a simple servlet used to get the message from a form and send it to the message server. To complete that task, the servlet must be both an HttpServlet and a MessageClient. Since Java does not allow such behavior, the main class extends the HttpServlet class, as shown in Listing 2. This main class contains an inner class that extends MessageClient. The outer class then creates an instance of the inner class.


public class SendMessageServlet extends HttpServlet{

private MessageClient m_messageClient;
private String m_serverName;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
try{
//Get server name
m_serverName = request.getServerName();
System.out.println("ServerName is " + m_serverName);
//Create message client to communicate with message server
m_messageClient = new ServletMessageClient();
System.out.println("Created Message Client");
m_messageClient.connectToServer();

//Get message and phone number
String phoneNum = (String) request.getParameter("PhoneNum");
String message = (String) request.getParameter("Message");

//Send message
m_messageClient.sendMessage(phoneNum,message);

//Display page to tell user message was sent
response.setContentType("text/html");
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/SendMessageForm.jsp");
dispatcher.include(request, response);
}catch (Exception e){
e.printStackTrace();
}
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

/** Inner class used to extend MessageClient */
public class ServletMessageClient extends MessageClient {
public ServletMessageClient(){
super();
}
public String getServerName(){
System.out.println("Returning ServerName " + m_serverName);
return(m_serverName);
}
}
}


This approach isn't true multiple inheritance because we used delegation. (i.e., MessageClient is extended by a member of the outer class and not the outer class itself), but the effect is the same. Although MessageClient could have been extended in a separate class, using an inner class allows it to access all the members and methods of the outer class. This makes it easier for the two classes to interact.

This example only extends two classes, but there is no reason why this technique couldn't be used to extend as many classes as needed by creating an inner class for each class that must be inherited.

source: http://www.javaworld.com/javaworld/jw-10-2005/jw-1024-multiple.html

donderdag 13 december 2007

Javapolis 2007

I was lucky to be present :)

Conference Day 1 : Wednesday December 12th


http://www.javapolis.com/confluence/display/JP07/Conf+Day+1

We focused on the Swing related sessions.

JavaFX by Jim Weaver



Very interesting speaker. Had the original idea to throw paper airplanes (of some value, I think free ebook) to people asking good questions.

Was my first real contact with java fx code. Looks like an easy syntax. Still for making a complete and complex gui I'm afraid you still end up with pages and pages of code. Anyway less than you would with swing.

He suggested we should play with the compiled version and have a look towards his blog for getting started information and examples.

The Elepehant is through the door example references that this project has left most of the work behind and is now wrapping up to get a stable production release.

Showed examples of syntaxt in general, binding, ... (need my notes to complete this)

sources:

http://www.javapolis.com/confluence/display/JP07/JavaFX (session)
http://www.javapolis.com/confluence/display/JP07/Jim+Weaver (speaker)
https://openjfx.dev.java.net/ (official project homepage)
http://learnjavafx.typepad.com/ (blog speaker)

Filthy Makeover by Chet Haase



Showed us a lot of relatively simply gui iprovements. Real life examples of gui's morphing from the standard grey ones towards fancy and therefore attractive user interfaces. The book is on my wishlist now.

Some of the topics (need my notes again)

* shadows
* blur
* gradients
* glass panels

sources:

http://www.javapolis.com/confluence/display/JP07/Filthy+Makeover (session)
http://www.javapolis.com/confluence/display/JP07/Chet+Haase (speaker)
http://filthyrichclients.org/ (book)

Web 2.0 Collaboration and Social Networking by Thomas Schaeck



This speaker was less interesting. End up showing a bunch of new web 2.0 tools for the lotus platform. Communities, Media Library, Blogs, Profiles, ... nothing really new. But most of all this was more like a commercial in conference disguise.

sources:

http://www.javapolis.com/confluence/display/JP07/Web+2.0+Collaboration+and+Social+Networking (session)
http://www.javapolis.com/confluence/display/JP07/Thomas+Schaeck (speaker)

Practical JRuby on Rails by Ola Bini and Charles Oliver Nutter



I had experience with Ruby on Rails (RoR) for profiling before and was very impressed back then. This session was not that new to me, the new part was the interaction with java. Which is interesting. Still all looked to have slow startup times... no surprises there :). Programmers also found some bugs while demonstration. Still this technology is impressive and very nice to play with. For prototyping I believe in this project.

The testing possibilities of this framework combined with the java code loading looked promising. Having nice mocking abilities, dynamic code loading and ease of specifications added to Java. Definitely something I wil get into.

sources:

http://www.javapolis.com/confluence/display/JP07/Practical+JRuby+on+Rails (session)
http://www.javapolis.com/confluence/display/JP07/Ola+Bini (speakers)
http://www.javapolis.com/confluence/display/JP07/Charles+Oliver+Nutter (speakers)
http://jruby.codehaus.org/ (official project homepage)

blueMarine by Fabrizio Giudici



blueMarine is a good looking image organizer. It is designed by and for photographer(s).

Allthough I couldn't always follow into detail this was an interesting session. The message I get is that swing is no framework but a great base for frameworks. We should look beyond swing, not to different approache but towards frameworks that built on swing. The most promising example libraries were swinglabs for general gui's, and netbeans rcp for more advanced, complex gui's. The last provides plugin funtcionality etc.

The programmer also showed some interesting options of his program (like the light panel and binding pictures towards a gps track) that are not available yet.

sources:

http://www.javapolis.com/confluence/display/JP07/blueMarine (session)
http://www.javapolis.com/confluence/display/JP07/Fabrizio+Giudici (speaker)
http://bluemarine.tidalwave.it/ (project homepage) http://swinglabs.org/ (swinglabs)
http://platform.netbeans.org/ (netbeans rcp)

recorded presentations : http://www.parleys.com/display/PARLEYS/Home

dinsdag 4 december 2007

Oracle and ON UPDATE CASCADE

We get errors from the following SQL on an Oracle database:

ALTER TABLE table_name
ADD CONSTRAINT constriant_name
FOREIGN KEY (TERMINOLOGY_ID)
REFERENCES TERMINOLOGY(TERMINOLOGY_ID) ON DELETE NO ACTION ON UPDATE CASCADE;


Finally we found out 2 things:
Oracle has no ON DELETE NO ACTION, use ON DELETE SET NULL instead
Oracle has no ON UPDATE at all for constraints so use trigger

So the fixed SQL looks like:

ALTER TABLE table_name
ADD CONSTRAINT constriant_name
FOREIGN KEY (TERMINOLOGY_ID)
REFERENCES TERMINOLOGY(TERMINOLOGY_ID) ON DELETE SET NULL;


and a trigger

sources:
http://www.psoug.org/reference/constraints.html
http://www.liacs.nl/databases/show.cgi?noaction
http://www.thescripts.com/forum/thread740824.html

vrijdag 30 november 2007

Directory Listing Denied

Als je een Directory Listing Denied krijgt betekent dit dat de server zo is ingesteld dat de inhoud van de directory afgeschermd is voor doorsnee gebruikers. Als je graag wilt weten wat er nu allemaal in die directory te vinden is kun je mogelijk toch nog resultaten vinden via google, bv:

http://www.google.be/search?q=http://www.domein.be/map&filter=0

Waarbij http://www.domein.be/map te vervangen door de url van de directory die je wilt testen.

woensdag 28 november 2007

(NL) IT'ers geen zin in jobhoppen

Door Harm Hilvers, woensdag 28 november 2007 11:49

Volgens het Britse werving- en selectiebureau ATSCo gaan werkgevers het de komende tijd moeilijk krijgen om nieuwe it-medewerkers aan te trekken. Het aantal it'ers dat van baan wil veranderen is erg laag, stelt ATSCo.

Don't be job hopperUit onderzoek van SkillsMarket en de Association of Technology Staffing Companies in het Verenigd Koninkrijk is gebleken dat het aantal it'ers dat op zoek is naar een nieuwe baan of openstaat voor aanbiedingen, gedaald is naar 28 procent, waar dit een jaar geleden nog 42 procent was. Een sluitende verklaring voor deze daling hebben de onderzoekers niet; wel zou meespelen dat de waarde van verkregen aandelenpakketten weer aan het stijgen is en dat werknemers daarom beter gemotiveerd zijn om bij hun huidige werkgever te blijven.

Volgens ATSCo zullen bedrijven het de komende tijd moeilijk krijgen om it'ers met specifieke vaardigheden in huis te krijgen. Verder zullen de salarissen omhoog gaan om nieuwe medewerkers te verleiden toch de overstap te maken. Ook wordt verwacht dat opleidings- en trainingsbedrijven het druk gaan krijgen. Bedrijven zullen meer geld moeten uitgeven om medewerkers te trainen, waar een personeelstekort tot voor kort kon worden opgevangen door het aannemen van nieuwe werknemers.

bron:
http://pro.tweakers.net/nieuws/50582/it-werknemers-hebben-geen-zin-in-jobhoppen.html

dinsdag 27 november 2007

ontology

I'm getting into new material right now.

The OWL specification based on RDF and XML should give an idea about what I'm working with these days.

And a wiki on Ontology in general here : http://en.wikipedia.org/wiki/Ontology
and
http://en.wikipedia.org/wiki/Ontology_(computer_science)

woensdag 14 november 2007

autocasting can be confusing

since java 1.5 there is a very easy autocasting for primitive datatypes to handle them as an object using the wrapper class.

An example:
List aList = new ArrayList();
aList.add(1);
aList.add(new Integer(2));


Now what when we want to delete one of these objects, it will think we give an index as parameter instead of the object we want to delete. So when deleting remember to use the wrapper class.

dinsdag 13 november 2007

blogger statistics

A tutorial on how you can use google analytics to add statistics to your blog.

http://www.infektia.net/how-to-track-your-blogger-statistics-with-google/

maandag 12 november 2007

html, css, js resources

A list of great css only designs, all based on the same content:
http://www.csszengarden.com

A list of css resources:
http://www.dezwozhere.com/links.html

A graphical index of css layouts to forget all about tables and start using css:
http://blog.html.it/layoutgala/

A generator to create your own ajax loader icons:
http://www.ajaxload.info/

Javascript prototype framework (and lots of derived frameworks):
http://www.prototypejs.org/

Joomla, an opensource CMS:
http://www.joomla.org
http://www.dutchjoomla.org

Visual index of lots of free Joomla templates:
http://www.joomlaos.de/joomla_template_galerie.html

color combination chooser (colorwheel):
http://www.colorsontheweb.com/colorwheel.asp

Firefox has lots of interesting developer plugins:
http://www.getfirefox.com
http://cappellehans.blogspot.com/2007/06/yes-i-use-firefox-my-plugins.html

google cheat sheet

Zeer handig overzicht van de mogelijkheden van google (en/pdf):
http://www.feedsforme.com/google/?cheatsheet

vrijdag 9 november 2007

hudson

One of the new tools I discovered is Hudson. This is a building system that can build your projects (ant/maven/...) from svn. More information here: https://hudson.dev.java.net/

vrijdag 19 oktober 2007

consumer producer java implementation

This is an example of a java implementation for consumer producer design pattern:

The Producer

public class Producer extends Thread {
private final int MAX_QUEUE_SIZE = 10;
private Queue queue = new LinkedList();

public void run(){
try{
while(hasMoreWork()){
//retrieve a result from somewhere
Object anObject = new Object();
//and make it available to consumer
putResult(anObject);
}
} catch(Exception e){
e.printStackTrace();
}
}

private boolean hasMoreWork(){
//TODO some check on the amount of work left for me here
return true;
}

private synchronized void putResult(Object object) throws InterruptedException {
//don't exceed max queue size
while(queue.size()>=MAX_QUEUE_SIZE){
wait();
}
//add new result to queue
queue.add(object);
notify();
}

public synchronized Object getNextResult() throws InterruptedException {
notify();
//await results
while(queue.isEmpty()){
wait();
}
//fetch next result
return queue.remove();
}

public synchronized boolean hasMoreResults() {
//see if we need to keep polling for results
return this.isAlive() || !queue.isEmpty();
}
}


The Consumer

public class Consumer extends Thread {

//a reference towards the producer
private Producer producer;

public Consumer(Producer p){
this.producer=p;
}

public void run() {
try {
//as long as producer is nog finished
while(producre.hasMoreResults()){
//fetch his results
Object result = producer.getNextResult();
//TODO do something with the results here
}
} catch ( Exception err ) {
err.printStackTrace();
}
}

}


source:
http://en.wikipedia.org/wiki/Producer-consumer_problem

donderdag 27 september 2007

mvn site:deploy on windows

I had to find a way to deploy javadoc towards a server. So I found out that the maven site has a reporting plugin for javadocs. To get all this working on windows follow these steps:

We need SSH so I installed cygwin with the following modules:

openssh
tcp_wrappers
zlip
unzip

After installation of cygwin run it and on the console execute the following command to import your windows system users into cygwin:
mkpasswd   -cl   >   /etc/passwd
mkgroup --local > /etc/group


If you are logging on to a domain you'll probably need to modify the /etc/group file to match the group ids with /etc/passwd.

The error I got because of this problem was something with setgid


Could be due to myself but I thought this referenced explanation was confusing. What you should do is open the /etc/passwd file. See for the line with as first element (separated by :) your username. Then see if the 4th element (counting from 1, so the GID in name:password:uid:GID:gecos:home:shell) matches the third field on the line with name Users in /etc/group. When these do not match edit the /etc/group file to fix this problem.


Now you can start the SSH server with the following command from within cygwin (don't know if altering users config requires restart of cygwin?):
net start sshd


And now you can go back to maven to deploy your site. Maven needs the following configuration. Edit POM to contain:
<distributionManagement>
<site>
<id>website</id>
<url>scp://localhost/cygdrive/c/PATH_TO_TOMCAT/webapps/mvnsites/${project.version}</url>
</site>
</distributionManagement>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</reporting>


Replace the PATH_TO_TOMCAT or any other server.


Then execute the following goals:
mvn javadoc:javadoc
mvn site:site
mvn site:deploy


resources:
http://pigtail.net/LRP/printsrv/cygwin-sshd.html
http://maven.apache.org/plugins/maven-javadoc-plugin/
http://maven.apache.org/plugins/maven-site-plugin/
http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-maven.html

woensdag 26 september 2007

scm using maven and subversion

You remember my first post on SCM? Well finally I had some time to get this running. Let me tell you how.

First create a project using maven2 (maven in 5 minutes):
c:
cd projects
mvn archetype:create -DgroupId=com.name.test -DartifactId=scmtest


Now edit the pom.xml file:
cd scmtest
edit pom.xml


To add the following line underneath the <url> tag (mvn scm plugin):
<url>http://maven.apache.org</url>
<scm>
<connection>scm:svn:file:///c:/svn-repo/scmtest/trunk</connection>
</scm>


Don't execute any mvn release goals yet because we still need to configure subversion. Let's start with creating the repo. Like you may have seen in the previous url to the repo I'm putting everything locally. Just for testing. When you have a server running somewhere you probably also know how to manage it (svn repo creation and config).
svnadmin create c:/svn-repo/scmtest


I'm not completely sure about the best way to get the standard svn repo structure in there? What I did is to create a /trunk, /branches and /tag folder and copying my mvn project into there. And then I import all of it in once.


Next you can import your project for the first time:
svn import file:///c:/svn-repo/scmtest -m "initial import"


Now check this out somewhere else first so you van continue working on an svn enabled project which is needed. You note the difference in the svn repo url? This time I only need what's in the trunk folder. Our actual project, not the tags and branches.
svn checkout file:///c:/svn-repo/scmtest/trunk c:/projects/scmtest-svn


Please note that for the next commands you need to be in the folder you just checked out. If you copied the command before this will be c:/projects/scmtest-svn/ so go there first.


And then add some files to the ignore list. The target directory and eclipse files for instance. This command requires the system variable SVN_EDITOR to be set. This could be set to the edit command which is the default text based editor of your windows system.
svn propedit svn:ignore .


Note that the dot (.) pointing to the current directory is required, don't forget it. That's the whole point (:-)) of being in the right directory.


So this command will popup the svn editor you set. And there add the following lines to this file:
target
.project
.classpath


And don't forget to save this file. So we can continue, we're almost there. In fact the svn repo is now up and running, we have the most recent version checked out, ... so now we can prepare our first release.

In real life you would only do this after some development, this time you can try out immediately by executing the following maven plugin:goal:
mvn release:prepare


Next you'll be prompted for the release numbers. You can use defaults by hitting enter each time.

If all goes well you're now working on a new SNAPSHOT version. You can verify this by looking at the pom file. The next step, to really get your new release in the mvn repo execute:
mvn release:perform


And if you had some problems you can try:
mvn release:rollback


Some more release goals.

To get the project into eclipse you can always run the following maven plugin:goal:
mvn eclipse:eclipse


Note how we already added the now generated eclipse files to the ignore list.

maandag 17 september 2007

about the java classloader

Some stuff you should know about classloading. The classloader makes 3rd party classes available to the jvm. So you can run your own code and use others libraries.

The first important thing (besides knowing how to set the classpath) is the hierarchy of the different classloaders.



You can always write your own classloader to append at the bottom of this hierarchy. Most servlet containers also provide their own classloader so look closely at the given documentation. For example this link points towards the classloader hierarchy of tomcat.

The loading of a class consists of 3 phases. This is described in the java specification:

1. loading
2. linking
3. initialization

To actually see this you can always execute some code with the verbose option of the jvm turned on:
java -verbose YourMainClass
This will log the class found and those phases. If you even want more information you can also try
java -verbose:class YourMainClass

The most common errors on this issue will be ClassNotFoundException and ClassCastException. Which you probably met before.

Another problem to be aware of is that each class (given the same package etc) can only be loaded once into the classloader. So if you provide an old version of your library on the extensions library of your jvm and add an updated version to your system classpath you will experience dependency conflicts. Only the old version will be loaded into memory because it's first in the classloader hierarchy. And if that old version is missing a method (or has another method signature) you'll get a NoSuchMethodException.

The next error can occur when a class is using native system libraries. When this library is not found the code will throw an UnsatisfiedLinkError. After this error occured the class will be obscured from memory so next calls on this class will give a NoClassDefFoundError. Which makes it tricky.

Other resources can be loaded from your classpath using ClassLoader.getResourceAsStream(String path)


resources:
internals of java classloading
demystifying classloading problems

maandag 3 september 2007

maven: add resources to ear

When building ear for weblogic you'll probably want to add a custom weblogic-application.ear to the ear. This file should be in the META-INF directory of the ear next to the application.xml.

To get this done add some configuration to the maven-ear-plugin like this:

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<earSourceDirectory>EarContent</earSourceDirectory>
<earSourceExcludes>**/application.xml</earSourceExcludes>
<modules>
<!-- modules here -->
</modules>
</configuration>
</plugin>
</plugins>


And make sure the folder you point to in this config contains a META-INF directory containing the weblogic-application.xml. No need to say you can add other resources to your this way. In fact this config will add everything in the EarContent directory, except for the excluded application.xml which will still be generated by maven.

donderdag 23 augustus 2007

Belgian IT'ers

Belgian IT people get highest education but lowest chance on more training when working.

Dutch source

zaterdag 28 juli 2007

my jstl frustrations

the in-container jstl interpreter functionality is great. And where there are greats things there are also less great things. Some of my frustrations on jstl:

no way to cast objects. In some cases this would be very welcome. For example when you have a superclass Item and some extending, more specifiek objects like AnITem and AnotherItem. In code you would be working with Item objects in general. In your view you need to have them casted towards a specifiek one. No way to do this in jstl so you need to cast in the controller which is not cool when you're working with a collection that could contain multiple kind of items.

Another one is the way you can't use numbers as a key for map collections. Need to provide another getter returing a string for that.

zondag 15 juli 2007

maven and jetty for quick dev deploy (2)

See previous post for more on general maven-jetty-plugin info. This time I'll explain how to get all this to work in eclipse. Wouldn't it be very easy to be able to execute this all from within eclipse? Follow these steps:

in Eclipse hit Run > External Tools > External Tools... to get the following popup:



First dubbelclick on Program on the left to create a new configuration. Then on the right complete information on the Main tab. Location is the path to your maven bin directory, Working Directory is your maven project and the arguments maven needs is
jetty:run


Next on the Environment tab add a New variable with name MAVEN_OPTS and value :
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n




And you're good to go. Launch the External tool you just configured which will start the jetty container. When you whish to debug you can create a new Run > Debug ... > Remote Java Application. All you need to set is the portnumber yout entered for the jetty arguments (4000 in my example).

sources:
o jetty documentation
o more on maven + eclipse

zaterdag 14 juli 2007

maven and tiger

By default the maven compiler plugin assumes you're working with 1.3 compatible sources. So tiger (java 1.5) sources will throw an UnsupportedClassVersionError.

The solution is to configure the maven-compiler plugin in your pom file to generate 1.5 sources like this:

<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>be.cappelleh.test</groupId>
<artifactId>test</artifactId>
<name>test</name>
<version>1.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- dependencies here -->
</dependencies>
</project>


source
o http://maven.apache.org/plugins/maven-compiler-plugin/

maven and jetty for quick dev deploy

Jetty is a java powered lightweight servlet container. It can be used as an embedded container bringing webapps closer to desktop applications. But that's another story. Here I will quickly explain how you can even quicker deploy your webapp on a jetty container using the maven jetty plugin.

All you need to do is add some configuration for the jetty plugin in you pom file. Like this basic config:

<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>be.cappelleh.test</groupId>
<artifactId>test</artifactId>
<name>test</name>
<version>1.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<useTestClasspath>true</useTestClasspath>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- dependencies here -->
</dependencies>
</project>


Next you can run your application using the following goal

mvn jetty:run


First time will take a bit longer because of the dependencies that need to be downloaded. Once up and running you'll see

[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 10 seconds.


And that means your application is waiting for you at (replace yourContext with your project context)

http://localhost:8080/yourContext


sources:
o jetty project homepage
o maven jetty plugin config
o maven jetty plugin goals
o more on jetty

woensdag 11 juli 2007

how to tell browser not to cache documents

I had to find a way to make sure the browser doesn't cache PDF documents on the local file system. IE for instance downloads a copy towards C:/Documents and Settings/userDirectory/Local Settings/Temporary Internet Files/ (which is the default, can be changed through Tools > Internet Options > Tab General and click Settings on panel Temprary Internet Files).

The solution was actually very easy, add the following HTTP headers to your response, that's it.

response.setHeader("Cache-Control","no-cache"); // for HTTP 1.1
response.setHeader("Pragma","no-cache"); //for HTTP 1.0
response.setDateHeader ("Expires", 0); //for proxy server
response.setHeader("Cache-Control","no-store"); //HTTP 1.1


source:
http://java.ittoolbox.com/groups/technical-functional/java-l/how-to-avoid-caching-of-pages-in-temporary-internet-files-folder-721490

hibernate: once set up you'll love it

Hibernate is lovely... it needs a little more attention to set up but once that's done no other persistence framework will beat it. So let's go over the setup steps here. I know there is a lot of information (good job on that from hibernate, springs lacks this at the moment) on this topic online, still it would be nice to have an overview (so I can get back to this summary myself).

dependencies

Let it be clear that using hibernate means you'll need to add some dependencies, jar files, to your project. If you use maven to manage these depencies this can't be hard.

your model

You'll need some POJO's or Plain Old Java Objects you want to store. These are simple Java objects with a ctor, some private properties and public setters and getters, also called JavaBeans.

mapping

Next you need to let hibernate know how these POJO's need to be stored in whatever JDBC enabled db you want to use. Therefore create a mapping file for all your POJO's. I use the following one as a reference, it comes from the hibernate reference documentation (see sources). Also make sure you check the mapping cheat sheet (sources) for more advanced mapping files.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="eg">

<class name="Cat"
table="cats"
discriminator-value="C">

<id name="id">
<generator class="native"/>
</id>

<discriminator column="subclass"
type="character"/>

<property name="weight"/>

<property name="birthdate"
type="date"
not-null="true"
update="false"/>

<property name="color"
type="eg.types.ColorUserType"
not-null="true"
update="false"/>

<property name="sex"
not-null="true"
update="false"/>

<property name="litterId"
column="litterId"
update="false"/>

<many-to-one name="mother"
column="mother_id"
update="false"/>

<set name="kittens"
inverse="true"
order-by="litter_id">
<key column="mother_id"/>
<one-to-many class="Cat"/>
</set>

<subclass name="DomesticCat"
discriminator-value="D">

<property name="name"
type="string"/>

</subclass>

</class>

<class name="Dog">
<!-- mapping for Dog could go here -->
</class>

</hibernate-mapping>


configuration

Then you can already configure hibernate. Create an xml file called hibernat.cfg.xml in your project resources folder and copy the following, adjusted for your needs, into it.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<mapping resource="events/Event.hbm.xml"/>

</session-factory>

</hibernate-configuration>


Check the hibernate reference documentation (sources) for more information on this config. Good to know is that the jdbc driver and sql dialect depend on the database you are using. Als the mapping resources at the bottom here need to point towards your mapping files you created earlier.

some util

You can use the following util code to access the hibernate session.


package util;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

}


hit it

Now you can start writing your services. In these services you retrieve the hibernate session, begin and commit transactions and in between this you'll saveOrUpdate, load, delete, list, ... your POJO's. For more specific queries you'll need to get into hql.

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

Person aPerson = (Person) session.load(Person.class, personId);

// The getEmailAddresses() might trigger a lazy load of the collection
aPerson.getEmailAddresses().add(emailAddress);

session.getTransaction().commit();



sources:
o hibernate reference documentation
o hibernate mapping cheat sheet
o hibernate tutorial, quick start

dinsdag 3 juli 2007

Spring Interceptors

Interceptors are very useful to intercept changes in your web application. Think of switching language, changing user id, ... Before Spring you would probably implement this using a filter.

Spring has a default interceptor for the language called LocaleChangeInterceptor. Look at the source of this one to see what you can do with interceptors.

It implements the HandlerInterceptor interface with the following methods (read api for more info):

void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

Callback after completion of request processing, that is, after rendering the view.

void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

Intercept the execution of a handler.

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

Intercept the execution of a handler.

To ease implementing only those you really need to implement there is the HandlerInterceptorAdapter.

Another example of using interceptors is to detect caching rules according to annotations


work out an example

woensdag 27 juni 2007

workaholics (NL)

70% zelfstandigen werkt meer dan 50u per week
25% zelfstandigen werkt zelfs meer dan 70u per week

bron
trends

woensdag 20 juni 2007

project management the big picture

Currently I use subversion for version control and maven (for some projects ant is used) for building. If you know ant but never used maven start reading about the diffrerences first. Most important is that these two projects have different goals. Maven is based on ant and provides more overall project management functionality, which is what I'm looking for here. As far as I know ant focuses more on platform independent building.

Still my IDE needs to be optimized so I need to look into the more general picture of project management. Like release management and of course the integration of all this into eclipse, the IDE of my choice.

An interesting thesis on this subject:

http://www.idi.ntnu.no/grupper/su/su-diploma-2006/dipl-enes-24feb07.pdf

SCM

System Configuration Management is what we're looking for. At the above link you can find a good dscription and brief history of SCM. Read it, it's interesting.

The document handles most aspects of SCM in the context of build and release management. Exactly what I'm looking for.

workspace pc for development, local file system, eclipse, sources (checked out)

versioning svn for versioning all sources assigning revision numbers and keeping track of changes, history, on file level

building make/ant/maven for compiling sources

release management maven, compiling sources for deployment, assign version number, on libraries/software level

dependency management maven, what libraries (jar for java) are needed to compile this artifact

repository management maven, managing a repositoruy of dependencies, holds several releases of libraries

change management following up changes of software components, like bugs, change requests, ...

Except for release and change management mvn + svn suit all my needs. Change management is a big issue and will most likely require more than one tool. For now I will just ignore it. Maybe I need to get back to this later on. What I really want to get into is the release management.

release management

Does maven have any support for release management? Yes it have, I'll find out in my mighty maven post.

mighty maven

You read my previous post on SCM?

Then we can continue by telling you more about maven. A great page to start is the maven project home page. For the quickies there is maven in 5 minutes.

Installation you'll really have to figure out yourself, is no more than unzipping package and setting some path variables.

Create your first project by the following commands
mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app
cd my-app


With the create goal you can generate the basic project structure and a basic pom file. The cd (change directory) was only to get yourself in your new project folder in order to continue.

To get this project into eclipse simply execute the following command.
mvn eclipse:eclipse

You can then import the project into eclipse as an existing java project. Dependencies will then be added to the classpath for your eclipse project (you might have to set the M2_REPO variable in eclipse to point to your maven repository). If you don't like the command way you can look for the maven eclipse plugin. This enables you to graphically manage your dependencies from within eclipse.

Then you can start developping, to compile use
mvn compile

You'll see that your junit tests form the test packages are executed before compiling the project itself. This is how it should be so keep your tests up to date.

Once the project is stable you can package project facets into jar with
mvn package

To be able to use this jar as a dependency in one of your next projects you can install the jar into your repository
mvn install


So far all of this was very straight forward. Now we'll get into more realistic situations with version control and release management.

Let us first configure our version control so we've got something to fall back to when we have a bad day. If you haven't any svn set up you can read the subversion setup post. Therefore add the following lines to your pom file

...
find out what's the best way to combine maven project structure and svn structure + give an overview of the different structures here, probably something like workspace/trunk/mavenproject/...

Also you'll want to deploy a complete project ... parent pom
war and ear packaging
...


resources
o list of build tools
o http://www.javaworld.com/javaworld/jw-10-2002/jw-1011-maven.html
o http://www.ibm.com/developerworks/java/library/j-maven/
o alternative maven repo

subversion setup

This is a quick subversion setup. really quick because to be honest it's my first time. Normally I only get the repository url and an account, setup done for me.

Start by downloading the latest subversion build for your system at http://subversion.tigris.org/project_packages.html.

Unzip this archive somewhere and ad the bin to your path variable.

Create your local repository with the following command
svnadmin create /path/to/repos


Next you can import your first project with the following command
svn import /tmp/project file:///path/to/repos -m "initial import"


An important note about your project structure,
subversion expects the following 3 root folders:

/tmp/project/branches/
/tmp/project/tags/
/tmp/project/trunk/


Then you can check the project out again with
svn checkout file:///path/to/repos/trunk project


All is done, you can now start importing other projects, commit changes, checkout elsewhere, etc...

Note that these examples all work locally so we can use the file:// protocol. Remotely this would be http:// or others.


how to delete a repository:
Deleting a complete repository is done by deleting the database
If you only want to delete a project or file use
svn delete -m "Deleting file 'yourfile'" file:///tmp/repos/test/yourfile


try and explain how to setup a svn server


resources
project home page: http://subversion.tigris.org/
ebook: http://svnbook.red-bean.com/en/1.1/ch01s05.html
cheat sheet: http://www.abbeyworkshop.com/howto/misc/svn01/

maandag 18 juni 2007

Unsuppported Class Version 49.0

I started programming Java with 1.3. Switching towards 1.4 was no problem at all. The 1.5 release at the other hand resulted in a lot of unsopperted class version exceptions.

The solution was easy, compile with -target 1.4. When I started working as a Java Developer I went through the same evolution. I started with 1.4 and bit by bit I could start using 1.5. And yes again those errors. So It's time to digg a bit deeper:

http://www.javaworld.com/javaqa/2003-05/02-qa-0523-version.html?page=1

donderdag 14 juni 2007

use http gzip compression

Looking for a way to speed up my webapps I found the following article:

http://www.onjava.com/pub/a/onjava/2003/11/19/filters.html?page=1

At first I got some nullpointer exceptions using the CacheFilter. Had to change the following line of code:

if (path!= null && path.equals("nocache")) {
chain.doFilter(request, response);
return;
}

into

if (path == null || "nocache".equals(path)) {
chain.doFilter(request, response);
return;
}

This way I avoided having this filter looking for non existing cached files when requesting the root context.

woensdag 13 juni 2007

notes java agents

resources:


debugging
http://www-128.ibm.com/developerworks/lotus/library/notes-eclipse/
http://www.domiclipse.com/frunobulax/domiclipse.nsf/pages/tut-debug-config-notes

maandag 11 juni 2007

a reusable sap pool

Through SAP JCO we can gather SAP information within Java. I'll explain the basics here while I'm revealing a library piece by piece.

SAP Connection

First we need to connect to SAP. Therefore create a connectionpool
public SAPPool(){
    // create pool
    JCO.addClientPool(
    ((String) properties.get(SAP_POOL_NAME), // Alias for this pool
    Integer.parseInt((String) properties.get(SAP_NR_CONNECTIONS)),// nr of connections
    (String) properties.get(SAP_CLIENT), // SAP client
    (String) properties.get(SAP_USERID), // userid
    (String) properties.get(SAP_PASSWORD), // password
    (String) properties.get(SAP_LANGUAGE), // language
    (String) properties.get(SAP_HOST_NAME), // host name
    (String) properties.get(SAP_SYSTEM_NUMBER) // system number
    );
    //...

Next you create a repository
    //...
    // Create a new repository
    repository = JCO.createRepository((String) properties
        .get(SAP_REPOSITORY_NAME), ((String) properties
        .get(SAP_POOL_NAME));
} //end of ctor

To reference a function through your repository
public IFunctionTemplate getSAPFunction(String functionName){
    repository.getFunctionTemplate(functionName);
}

Also you can get the client
public JCO.Client getSAPClient(){
    JCO.getClient(poolName)
}

And very important is not to forget to release it again
public void releaseClient(){
    JCO.releaseClient(client)
}


Because It's so important not to forget releasing your resources again and because of some other default handling of calling SAP functions we'll use an abstract class. Read more about my interface vs abstract class post to understand why.

What are the defaults?

get function let's do this in the ctor which takes the functionName as an argument. Also we preserve some references towards the input, output and tables parameterLists (SAPPool references to class holding the previous posted code)
public BaseSAPFunction(String functionName){
    IFunctionTemplate ftemplate = SAPPool.getSAPFunction(functionName);
    function = new JCO.Function(ftemplate);
    input = function.getImportParameterList();
    output = function.getExportParameterList();
    tables = function.getTableParameterList();
}

set input next we need to set the input parameters. In the BaseClass I did so by having an abstract method handling this. In the actual implementation the input parameterlist can be referenced. The actual implementation will follow in calling a function.
public abstract void setInput();

execute function for actual execution of function first get a client on which you can invoke the execute function like this
public void executeFunction(){
    client = SAPPool.getSAPClient();
    client.execute(function);
}

handle results this will also be abstract here because this depends on the actual implementation. Here it returns an Object for compatibility with non 1.5 code. This implies that you'll need to cast it the right way. If you can ensure you'll have only 1.5 using this library then use generics. Again the actual implementation will follow in calling a function.
public abstract Object getData();

release client is done by executing
    SAPPool.releaseClient();


All together this wil be chained in the right order with some general execute function like the following
 public Object execute() {
  setInput(); //see implementation for details
  executeFunction();
  Object obj = getData(); //see implementation for details
  SAPPool.releaseClient();
  return obj;
 }


calling a function

Now for calling a specific function I extend the previous explained BaseSAPFunction. Then I only need to make a ctor calling the super ctor with functionName as argument and implement the 2 abstract methods (and maybe some helpers). Classes using this function invoke the execute() method and cast the Object. That's it.
public class SomeSAPFunctionCall extends BaseSAPFunction{

    public SomeSAPFunctionCall(){
        super("ZBAPI_SOME_FUNCTION");
    }

    public void setInput(){
        input.setValue("fieldValue", fieldName);
        //more here
    }

    public void getData(){
        SomeDTO dto = new SomeDTO();
        JCO.table table = tables.getTable("TABLE_NAME");
        if(table != null) {
            do{
                dto.setAString(table.getString("A_STRING"));
                dto.setAnInt(table.getInt("AN_INTEGER"));
                //more here
            } while(table.nextRow());
        }
        return dto;
    }
}


usage
SomeDTO dto = (SomeDTO)new SomeSAPFunctionCall().execute();


resources

zondag 10 juni 2007

about collections, the basics

Let's talk about collections. You've got several options, only one is right.

First of all an overview of the Interfaces



Map: have key and a value. With the key the value can be looked up. These keys are unique so there is no duplication (at least not for the keys, you could insert to identical objects as long as they are stored with a different key).

You've got general Map which are not sorted, no garantee of any order. If order is needed you must look for a SortedMap implementation.

Remember that order is defined using the compareTo() method (Comparable). Custom objects need to implement this. The uniqueness is defined using the equals() method of java.lang.Object (which all objects extend). Good to know is that default implementation checks the actual instance of an object (=memory address). Override the equals() (and hashCode()) method to meet your needs. By example a user could be compared by email, etc...

When you add a custom object to a sorted collection while it doesn't implement Comparable you'll get the following error:
Exception in thread "main" java.lang.ClassCastException: NoComparable cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(TreeMap.java:542)
at TestComparable.main(TestComparable.java:8)


Collection: only store values so no way to lookup. This means you would have to iterate the elements in order to find a specific one.

No keys here, uniqueness depends: Set and SortedSet can't contain duplicates, List can. The List is actually indexed, so the order is the one in which elements were added. The Set has no order what so ever, the SortedSet orders it's elements with the compareTo() method (or a given Comparator).

A note on sorting and performance: Use it only when really needed. A sorted collection has it elements sorted all the time. This means on every update (adding, removing, changing an element) the collection needs to resort and that takes some time and memory. Another solution is to use an unsorted collection and sort it only when presenting to the user.


This is only a quick start, you now only got the interfaces. You still need to find the right implementation. Look at the javadocs and don't forget that besides sun there is also the jakarta commons collections... More might follow.

interface vs abstract class

I'll keep it simple...

Interfaces should be seen as a contract, they define some method signatures which need to be implemented by any implementing class. Use Interfaces for code that can change easily.

A great example of how to use interfaces is the Strategy Pattern (PDF). Follow the link for a detailed description and example. In general the strategy pattern provides an easy way to implement different strategies (logics) for achieving your goal. On top there is an interface.

Another example of interfaces are the collections In fact it's a good practice to use these interfaces in your method signatures, this improves the flexibility of your code. You can then easily switch collection implementation. Example:

private List list = new ArrayList();

public List getList(){
return list;
}
public void setList(List list){
this.list = list;
}


Abstract classes can also oblige an extending class to implement some methods. The difference is that an abstract class can do more. You can add completed methods, fields, ... So an abstract class can provide general implementation, defaults and a contract for some other methods of which the logic will be defined in subclasses.

Don't forget!

zaterdag 9 juni 2007

jakarta commons

The jakarta commons project is a great example of reusability. It's a collection of utilities that can be used independently. The only problem is a lack of documentation. There are some books available. I'll look into these as soon as possible (just ordered a copy of the jakarta commons cookbook, ISBN:059600706X).

Some I used so far are:
commons.lang.StringUtils
commons.lang.builder.*
commons.collections.CollectionUtils
commons.collections.Transformer


...

For anyone who wants to get involved:
http://jakarta.apache.org/commons/volunteering.html

resources:
http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html
http://jakarta.apache.org/commons/
http://www.javaworld.com/javaworld/jw-07-2005/jw-0725-chain.html
http://www.javaworld.com/javaworld/jw-10-2002/jw-1025-opensourceprofile.html

I recently wrote some code to convert time from the HH:mm notation towards decimal notation and vice versa, could it be done with commons and if not see for submitting code.


What about some tool to query javadoc in order to find commons code quickly?

donderdag 7 juni 2007

my java resources

The following is a list of my freguently used java resources, I might keep this up to date.

If anyone has more resources please let me know!

client side validation

I was looking for a good validation framework. Some options:

I eventually used jsVal. The inline form initialisation is very easy in use. Regex are supported and some specific validations can be done with callback functions.

Errorfields are marked by defining a css class. Besides that a popup shows a more informative message. These can be translated using javascript.

Custom validation messages can be defined using the err="your message" attribute. Only works in validateStandard() mode. The validateCompleteForm() mode in which all fields are validation in once seems to ignore these personal messages.

When using callback you need to set required="1".

I used a little trick to validate multiple fields (like compare a to be) by adding an onclick="return moreValidation()" event to the submit button.

To end this post an article about a more complex solution. Uses server side validation icw ajax to simulate (towards user) client side validation.

woensdag 6 juni 2007

fn:replace carriage return with br

So I have a String that needs to be passed through as a javascript method argument. Problem is this String is user input and therefore can contain newlines so code can be scattered over multiple lines resulting in js syntax errors, example:


functionName("a correct string argument","this one is
scattered over multiple lines and therefore generates js syntax errors");


Easy, lets replace these newlines with the fn:replace tag... Didn't turn out to be so simple at all, "\\\r\\\n" is not accepted with jstl. Read the following threads for some suggestions:

http://forum.java.sun.com/thread.jspa?threadID=614154&messageID=3427211

http://mail-archives.apache.org/mod_mbox/jakarta-taglibs-user/200404.mbox/%3c20040413170630.M35388@pdragon.net%3e

Important! In case of just formatting (not syntax problem like me) you can always use <pre> + css

Eventually I just created an extra getter in my model returning the corrected string, if you don't know how to do this see:

http://www.rgagnon.com/javadetails/java-0454.html


When always running on the same system you can also use System.getProperty("line.separator") in your replace.


about spring SimpleFormController

When extending the SimpleFormController you might need some referenceData to be available after submitting the form. For example usefull when formView and successView are equal. This can be achieved by overriding the


/**
* On form submission redisplay the form.
*/
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response,
Object command,
BindException errors) throws Exception {
//TODO handle your command here
//return to formView (so referenceData is still present)
return showForm(request, response, errors);
}


(my tiny thread on this: http://forum.springframework.org/showthread.php?p=123407)


And to finish this post, you might need a collection as command object. In that case you'll need a wrapper class because collections are not supported by default. Example for list:


/**
* Helper class to use a list as spring command object. By default this is not
* supported so need to use this wrapper class in order to have indexed access
* to list.
*
* @author Hans Cappelle
*
*/
public class ListWrapper {

/**
* The actual list to perform actions on
*/
List list = new ArrayList();

/**
* def ctor
*
*/
public ListWrapper() {

}

public ListWrapper(List list) {
this.list = list;
}

// setters & getters

public List getList() {
return list;
}

public void setList(List list) {
this.list = list;
}

}


review generics and see if this can be applied to this wrapper

yes I use firefox, my plugins

I use firefox for developping webclient frontends. That's why:

  • I can change my css file on the fly and see what happens in browser with EditCSS

  • Well the users will most likely use IE instead so make sure to test your desing in IE as well. Wouldn't it be extremely usefull if I could check this with firefox... check IETab.

  • HTML that looks the same in all browsers starts with valid HTML (and ends with IE :-)). So validate your pages with HTMLValidator.

  • What color is that, wait I have a colorpicker called ColorZilla.

  • You can even measure the dimensions of your elements in pixels (without looking at your source) with MeasureIt.

  • And while using firefox make sure to report any relevant bugs with the TalkBack plugin (that's installed by default I guess).

  • Don't forget performance, well that's not really frontend but I can check it in my firefox client with FasterFox.

  • Javascripts can be so annoying, I use the Javascript Debugger if I'm really lost.

  • Linkchecker, what's in a name?

  • The DOM Inspector I don't really use a lot but I can imagine this being very handy for some people among us (comes with firefox).

note 1 : For the lazy ones there's also a complete (much more than I need so I don't use it) plugin at http://chrispederick.com/work/webdeveloper/


note 2 : and I'm not the only one, so check this google result.


note 3 : I can't access the actual mozilla addons page here so links might be broken, let me know.


Some shortcuts I often use are:

  • CTRL + D : bookmark

  • CTRL + J : downloads

  • CTRL + TAB : travel tabs

  • CTRL + T : new tab

  • CTRL + N : new window

  • CTRL + U : page source

  • CTRL + L : addressbar
complete list:
firefox cheat sheet

GUI's should be simple, attractive and user friendly

Ok I'm a programmer and graphical design is just not my thing. But that doesn't mean my applications don't need an appealing frontend.

So let's see what I do to present my applications without shame. Any comments are more then welcome I'm here to log my solutions and to learn from people reading them.

I'm going to explain my methods for graphical design of web applications. Mostly HTML, CSS and a bit of javascripting. Swing is been to long to log any information on that.

technical


It's important to seperate your view (fronted) from the logic and backend. The same way you should seperate your styling from the presentation. Meaning you'll be writing plain HTML and add a reference to your external css file. This way you can simply change the look'n feel, make several themes, ...

usability


Don't forget about usability, make your applicatons available to everyone. Meaning you'll have to provide the alt attribute for your img tag, title for a tags, ...

More in general it's always good to know where you are so make a crumbtrail on your page. This is easily automated by letting a tokenizer play with your request url.

Read more about usability, I'm no expert.

html/css


div vs table


You'll need a gross layout first. Sketch some sections like header, menu, content, footer, crumbtrail, ... on your page and translate these to HTML using div elements with an id. Don't use tables for this. Tables are ment for listing data in... tables indeed. Not for positioning.

A simple position is the header on top, a menu on the left (and another on the right?), your content in the middle and a footer to end your page with.

By putting al these elements in a container div you can set a width for your website or some other general stuff (no need to change body for that).

You might want to refer to the strict doctype for better support on different browsers.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div id="container">
    <div id="header">header</div>
    <div id="leftmenu">leftmenu</div>
    <div id="rightmenu">rightmenu</div>
    <div id="content">contentv/div>
    <div id="footer">footer</div>
</div>
</body>
</html>


For the css try the editCSS firefox plugin so you can give this website a rocking layout. Also read my blog about colors to get a cool colorscheme.

You can get some dummy text for visualising your pages at http://www.lipsum.com/.


Referring to the div elements is done with the id css selector shown below. I'll only give you some positioning css and borders so you can see you don't need any tables. Colors and an actual design is up to you. You might want some inspiration.

All I do is giving the leftmenu a width and float it to the left. Same for the right menu, only float to the right this time :-). Don't forget the clear property on your footer! This will make your footer appear at the bottom of these two vertical bars. Now the content div is still in the way of your menus. Give this one a left and right margin equal to the sizes of these menus to fix that (I actually added some more for some spacing).

#header{
    height:80px;
    border:solid 1px blue;
}
#leftmenu {
    width:200px;
    float:left;
    border:solid 1px red;
}
#rightmenu {
    width:200px;
    float:right;
    border:solid 1px green;
}
#content{
    margin:0px 210px 0px 210px;
}
#footer{
    clear:both;
    height:20px;
}


Read some css and maybe html tutorials when you don't understand this code.

sliding doors


Google on the sliding doors effect. It's way more advanced than this but I wanted to mention it anyway.

javascripting


Javascripting became very popular together with the rich web clients. Currently Java is even looking to include a javascript compiler with their jre.

nifty corners


When only using css and html you get a very rectangle design. You can always add background images and play with it using css, but that's not the simple way I'm looking for. It's easier to round some corners by using the nifty corners library.

Nifty("div#box","big");


prototype


Some common functions to ease javascripting can be found in the prototype library. More information here. Don't confuse this with the prototype object.

scriptaculuous


Scriptaculuous (note the uber url) takes prototype to the next level. You can add many dynamic effects to your website this way.

ajax


Google is all over it, check gmail, calendar and many more. For websites you always perform a get of your page, maybe a post of your form input and then again a get. Several requests are needed. And a request means a refresh of your page content. AJAX hides these requests for the user by posting data and updating the page with the requested content using javascripting on the background. While loading the data very typical ajax please wait images are shown.

The prototype has some very easy functions to perform these ajax submits. Read all about it here.

graphics


I use graphics for icons mostly.

JPG vs GIF


GIF images have an indexed, fixed number of colors. 16, 32, 64... maybe 256 colors but that's it. GIF images are used for small icons, backgrounds with little detail, ... Don't use a GIF for your self portrait. Pictures need a lot more colors so you'll need to make JPG pictures of it. For online take a good compression rate of about 65%. For archiving on your local computer (I don't recommend JPG but if you have to) take a higher rate like 85% (good balance). Make sure you leave a copy of the original picture. Anytime you save your JPG you will loose data, even when you save it with the same compression (or even higher) rate.

paint.net


Don't compare Paint.net with the cripple paint you get with windows. First of all Paint.net is free :-). It can work with layers, has gradient, ...

vrijdag 18 mei 2007

excel export from webapp HSSF IE

While using the spring-framework (rocks!) I used the poi framework of jakarta to generate excel sheets. All went well in firefox but when I tried this with Internet Explorer the file was broken. The application opening it couldn't find the temp file.

My solution for this is in using the correct response headers. I found these by looking at an opensource project with excel export functionality (thx 2 phpMyAdmin).


Using the following headers works for me:

//control cache, these make the difference
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "Public");
//these are xls specific
response.setHeader("Content-Disposition", "attachment; filename=action.xls");
response.setHeader("Content-Type", "application/vnd.ms-excel");


So good luck with it, also check your filename for characters not allowed by your filesystem.

updating blob field oracle with hibernate results in > 4000 bytes error

Ok so writing BLOB fields in Oracle (with hibernate) could give you a bla bla length > 4000 bytes error. [todo: lookup exact error] First of all I'll explain why. The BLOB fields in oracle work with a pointer and that pointer is 4000 bytes. The actual data is stored elsewhere. So your problem is that you're trying to write to this pointer instead. [todo: lookup source]

I believe (didn't have time to test yet [todo]) that the problem is within the driver. So first of all get the latest driver you can get.


oracle jdbc driver version


com.oracle.jdbc
jdbc-thin
1.2
test


The following information is for completeness only.

hibernate version


org.hibernate
hibernate
3.2.0.ga


hibernate mapping

<property name="xml" lazy="true" not-null="true" column="xml" />

java property

/**
* xml data of this audit
*/
private byte[] xml;

public byte[] getXml() {
return xml;
}

public void setXml(byte[] xml) {
this.xml = xml;
}

column definition

XML BLOB not null

sapjco problems

When using the java sap connector there are several things to keep in mind. Start by following the instructions in the given link ^.

You need a reference in your project to the sapjco.jar file. You could put this one on the lib of your jdk installation (%JAVA_HOME%/lib/ext) but I wouldn't. Read aboout classloading instead.

The same for the two ddl libraries: librfc32.dll en sapjcorfc.dll can be put in your jdk lib, %WINDOWS%/system32/ or any where else. Just make sure this path is on your system variable PATH.

It's important to start logging errors from the very first run. Because if the sapjco.jar was found on your classpath but it didn't find the dll's than only the first error will give you this information. It will print an UnsatisfiedLinkError and it should print the path where it's looking as well.

You can do this yourself in Java (f you hava the rights to) with the following line of code:


System.out.println(System.getProperty("java.library.path"));


Solving this problem is easy (put the ddl's on that path) but can be tricky because for the next calls on that sapjco.jar it will return a ClassNotFoundException.
So if you missed the first error you might be wondering why your jar wasn't found (while it was).

just found an interesting article about external java sources in domino server. Should be possible to add a jar file to a project as well. More articles on the same very interesting website, also on classloading.

profiling Java

Profiling is important, it can show bottlenecks in your application and so help you solve these. An optimized application will run faster so users will be hapier.

I mostly use eclipse for development (WTP project). Check my post on this blog about my eclipse plugins as well

Before version 3.2 of eclipse I had a simple eclipse plugin for profiling. The link points to a good tutorial for setting this one up for most servers. Problem with this one is that it's not supported anymore and doesn't work with and all above 3.2

Eclipse profiler - plugin for profiling Java applications inside of Eclipse. NOTE! Project is dead and does not work on new versions of Eclipse. Use other open source (such as TPTP) or commercial profilers. SWT components library - set of additional SWT

I tried the eclipse TPTP project. It's a bit overkill but it works. I didn't get it to work using only the project documentation. Note you have to install the AC controller seperately. For the different server configurations I found another tutorial. This one worked for tomcat: eclipse TPTP tomcat howto.

todo: test and describe other server configurations like weblogic, ...

my eclipse plugins

Well most of them at least, I'll try to keep this list updated:

  1. WTP project : for developping web and enterprise applications, also includes xml validation etc
  2. TPTP project : for testing and profiling applications
  3. green : for UML integration
  4. SQL explorer : database management through jdbc
  5. PHPeclipse : php integration
  6. m2eclipse : maven integration, there is also an maven plugin for generating eclipse projects
  7. RDT : ruby integration