Thursday, November 25, 2010

Referential Integrity - Good or Bad?

In relational database world such as MySQL, PostgreSQL, Derby / JavaDB, and HSQLDB RDBMS there is Referential Integrity.

It's very useful to avoid consistency mistakes with foreign keys during operation.

It's useful when we live in *relational* world. But during development of a modular application and agile, frequent upgrades.. Is referential integrity helping or hindering productivity?

Consider an application that has a Customer table that has a column an refers to a Country table. Each deployment would have its own Customer table data. However, Country table is pretty much "shared" globally. Country table is never meant to be modified from the admin's perspective.

When there is a new country or modification, new version of application will be released, containing an update to Country table.

In old-school style of upgrades, Country table should be replaceable similar to how we replace files during upgrade, i.e. overwriting a file called countries.xml.

However, due to referential integrity, it's not possible to simply drop the table, recreate it with the data. We have to issue proper DML SQL statements to update the data from the "current" version (yes, we must detect what is the current version) to the new version.

All in the name of not breaking foreign key checks aka referential integrity.

Isn't RDBMS making simple things complex?

Monday, November 22, 2010

Deploying Eclipse BIRT Web Viewer to GlassFish 3.0.1 on Ubuntu 10.10

Eclipse BIRT is free / open source reporting engine for Java.

A commercial BIRT Report Server is available from Actuate (the company behind Eclipse BIRT). While Eclipse BIRT does not provide a free/open source reporting server, the BIRT Runtime provides a simple Eclipse BIRT Web Viewer.

Eclipse BIRT Web Viewer installation instructions for several Java EE application servers are here.

Here I share my own experience installing Eclipse BIRT 2.6.1 Web Viewer under GlassFish 3.0.1 Java EE Application Server :

  1. Install package sun-java6-jdk dan ttf-mscorefonts-installer
    Package ttf-mscorefonts-installer contains Microsoft fonts needed by some reports.

  2. Install GlassFish 3.0.1+.
    When asked for JVM, enter: /usr/lib/jvm/java-6-sun
Run GlassFish. In Terminal, go to GlassFish directory and type:
bin/asadmin start-domain

Default GlassFish domain is : domain1

It will show something like:

tuneeca@geulis:~/glassfishv3$ bin/asadmin start-domain
Waiting for DAS to start ......
Started domain: domain1
Domain location: /home/tuneeca/glassfishv3/glassfish/domains/domain1
Log file: /home/tuneeca/glassfishv3/glassfish/domains/domain1/logs/server.log
Admin port for the domain: 4848
Command start-domain executed successfully.

Now that GlassFish is running, you need to deploy Eclipse BIRT Web Viewer:
  1. Download birt-runtime-*.zip from BIRT Downloads under BIRT Runtime.
    Inside this archive there is birt.war file.
  2. Deploy birt.war through GlassFish admin ( http://localhost:4848/ ) or by copying birt.war to folder glassfish/domains/domain1/autodeploy/
    In the log file glassfish/domains/domain1/server.log (to follow this file, use tail -f ) you should see something like :
    [#|2010-11-22T16:55:54.411+0700|INFO|glassfish3.0.1|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=23;_ThreadName=Thread-1;|[AutoDeploy] Selecting file /home/tuneeca/glassfishv3/glassfish/domains/domain1/autodeploy/birt.war for autodeployment.|#]

  3. Check BIRT Web Viewer is running at : http://localhost:8080/birt/
You will need two additional libraries, Apache Commons Logging and JDBC Driver for your database.

Commons Logging

Without this, you'll get an error: java.lang.NoClassDefFoundError: org.apache.commons.logging.LogFactory
birt.war needs Apache Commons Logging.

Copy the file commons-logging-1.1.1.jar to folder glassfish/domains/domain1/applications/birt/WEB-INF/lib
Then reload the webapp :

touch glassfish/domains/domain1/applications/birt/.reload

MySQL JDBC Driver

If you get an exception like:

An exception occurred during processing. Please see the following message for details:
Cannot open the connection for the driver: org.eclipse.birt.report.data.oda.jdbc.dbprofile.
    org.eclipse.datatools.connectivity.oda.OdaException ;
    java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

For MySQL:
Copy file mysql-connector-java-5.1.13.jar to glassfish/domains/domain1/applications/birt/WEB-INF/platform/plugins/org.eclipse.birt.report.data.oda.jdbc_[version]/drivers

For other databases, copy the appropriate JDBC driver(s).

Go to: http://localhost:8080/birt/

Now you should be able to run BIRT reports over the web, on GlassFish!

Sunday, November 21, 2010

Vaadin TouchKit and Google App Engine = Session expired / Out of sync errors?

I've been developing with Vaadin, Vaadin TouchKit (for Mobile UI), and Google App Engine... and getting a lot of these messages:

Out of sync Something has caused us to be out of sync with the server.
Take note of any unsaved data, and click here to re-sync.

Also session expired messages......

Any ideas / solutions / workarounds ?

I'm considering switching to JSF 2.0 + PrimeFaces ...

Saturday, November 20, 2010

Gradle Build for Spring Framework and SLF4J without Apache Commons Logging

Gradle build system supports Transitive Dependency Management.

It's very useful when you depend on a library, say Spring Framework, that uses Apache Commons Logging (artifact commons-logging:commons-logging), but you want to use another library like SLF4J and want to exclude Commons Logging.

Here is the Gradle build to exclude the commons-logging transitive dependency.

repositories {
mavenCentral()
}

configurations {
compile
runtime
all*.exclude group: 'commons-logging' // this is where we exclude
}

dependencies {
compile group: 'org.springframework', name: 'spring-web', version: '3.0.5.RELEASE'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.6.1'
runtime group: 'org.slf4j', name: 'slf4j-jdk14', version: '1.6.1'
runtime group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.1'
}

// Example usage: Copy dependencies
// e.g. to the Google App Engine WEB-INF/lib directory
task copyDependencies << {
copy {
from configurations.compile
from configurations.runtime
into 'war/WEB-INF/lib'
}
}

Patching Java App on Deployment Site?

Application using Java (or any compiled programming language, like Scala, C++) is more cumbersome when you want to patch a running application on a deployment site.

Meaning, while Java development is pretty good when you have an IDE and the development environment setup properly... it starts becoming a nightmare when you want to debug/edit/diagnose your application on a deployment site that has none of those goodies.

Compared to an interpreted programming language, like PHP, Python, Groovy, ... you can change a single line of file and have your changes readily available. Sometimes without restarting the application...

Intermezzo: I say "sometimes" because a moderately complex application will have caches and other infrastructure that can make simple "refresh-driven patching" model impractical. One can say that "caching" is similar to an On-Demand Compiler. The difference is that cache generator is bundled with the application, while Java class/JAR files can only be generated by javac compiler plus the appropriate build system.

(Partial) Alternative #1: Remote Debugging aka JPDA (Java Platform Debugger Architecture)

With this, it's possible to connect to a running application, even remotely, and debug whatever it's doing, still using your trusty IDE on your development laptop.

However, deploying the modified application is still a problem. You can compile and build your application in your laptop, but deploying it to the remote site is a different issue.

(Partial) Alternative #2: Use A (Java EE) Application Server

Whether you use Tomcat, GlassFish, JBoss AS, Jetty, or any other application server... Deploying the application from your development workstation should be trivial.

You need to have the full application sources first, and able to build it. But after you can build it you can deploy relatively easily.

Of course, this still doesn't solve the problem that you can't work without a workstation with proper development setup.
And you can't just "change a file" in the deployed host.

You still need a development setup!

Any suggestions?