A piece of very old assembly code

A couple of weeks ago I’ve been looking through some old backup CDs. To my surprise I have found some old source codes written more than 10 years ago. Of course, most of them were unfinished and ugly. Some of them turned out to be totally useless rubbish which made me feel embarrassed. But I have also found a couple of interesting things. For a moment I was amazed… I still cannot believe that I used to have so much patience to write code in pure assembler.
Here is a sample source code. It was supposed to be a 4KB intro.
The intro was written in 1999 (a twilight of MS-DOS era) in pure 80×86 assembly language. It should run on 32-bit Windows. The executable itself is 3529 bytes long and it is .COM executable file. Its name was supposed to be “Loser”, but I really do not remember why such a title was chosen. There were some nasty tricks used to make the code as short as possible… but who would care about them today? It doesn’t generate any sound effects or music, but trust me it was also possible in assembler! The visual effects were of course supposed to make an impression of a damaged TV-set (so please do not adjust your monitor:).
I have recorded and uploaded this animation on YouTube:

If you would like to compile source code of this “demo” you should use Borland’s Turbo Assembler and Turbo Linker.

Hibernate in OSGi bundle

This is my third post about OSGi technology. This time we’re going to do something more advanced. We will create Hibernate-based application working in OSGi bundles. It can be used as a basis for more complex multi-layered SOA killer-app ;-)

In a few words… We will create a Maven project that will consist of two modules. I think that it would be nice to have some kind of a starter for bigger Hibernate applications. That’s why I’m going to separate Hibernate libraries from the mappings and configuration. Both modules are to be packaged as bundles:

  • osgi-hibernate-classes – will be a wrapper bundle for Hibernate JAR and all its dependencies
  • osgi-hibernate-mysql-test – will contain configuration, mappings the application itself

Both these projects will have a common parent POM file.

Parent POM

<?xml version="1.0" encoding="UTF-8"?>
<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>com.lukaszbaran.simpleosgi.db</groupId>
	<artifactId>parent-pom</artifactId>
	<version>1.0</version>
	<packaging>pom</packaging>
	<name>Hibernate on OSGi</name>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<modules>
		<module>osgi-hibernate-classes</module>
		<module>osgi-hibernate-mysql-test</module>
	</modules>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.6</version>
		</dependency>
		<dependency>
			<groupId>sax</groupId>
			<artifactId>sax</artifactId>
			<version>2.0.1</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.3.0.ga</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-commons-annotations</artifactId>
			<version>3.3.0.ga</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>javax.persistence</groupId>
			<artifactId>persistence-api</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>jsr250-api</artifactId>
			<version>1.0</version>
		</dependency>
	</dependencies>
</project>

osgi-hibernate-classes module

This wrapper bundle is very simple, as it won’t have any Java code. It will only consist of POM file which should be located in osgi-hibernate-classes sub-directory and look like this:

<?xml version="1.0" encoding="UTF-8"?>
<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>
	<parent>
		<groupId>com.lukaszbaran.simpleosgi.db</groupId>
		<artifactId>parent-pom</artifactId>
		<version>1.0</version>
		<relativePath>../pom.xml</relativePath>
	</parent>
	<groupId>com.lukaszbaran.simpleosgi.db</groupId>
	<artifactId>osgi-hibernate-classes</artifactId>
	<packaging>bundle</packaging>
	<version>1.0</version>
	<name>osgi-hibernate-classes</name>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<version>1.4.3</version>
				<configuration>
					<instructions>
						<manifestLocation>META-INF</manifestLocation>
						<Import-Package>
							org.apache.commons.logging,
							javax.sql,
							javax.naming*,
							org.w3c.*,
							org.xml.sax,
							org.xml.sax.ext,
							org.xml.sax.helpers,
							!*
						</Import-Package>
						<Embed-Transitive>true</Embed-Transitive>
						<Embed-Dependency>*</Embed-Dependency>
						<DynamicImport-Package>
							com.lukaszbaran.simpleosgi.db.test.entities.*
 						</DynamicImport-Package>
						<_exportcontents>
							org.hibernate*
						</_exportcontents>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.2.6.ga</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
</project>

The most important part of this POM file is the configuration of maven-bundle-plugin. What we want to achieve is to have Hibernate JARs embedded in an OSGi bundle. There are several ways of achieving our goal. It means that the solution presented here is not the ultimate and best solution. But it’s the working one! Here, we are putting all the JARs necessary for Hibernate into a bundle. The JARs are not be unpacked and they will appear in the main path inside of the bundle. This is achieved by the two sections:

	<Embed-Transitive>true</Embed-Transitive>
	<Embed-Dependency>*</Embed-Dependency>

The * character in Emded-Dependency tells plugin to include all dependencies from POM file (of course, it includes dependencies from our parent POM). The Embed-Transitive section causes that all the transitive dependencies will be included as well.

Another important point is Import-Package. This is where we declare what other (external) packages will be referenced by our code. In other words, all external dependencies have to be listed here.

OK, now comes the most tricky part in this tutorial – the packages that our wrapper will be exposing to other bundles. In this case we want to expose Hibernate to other bundles. To achieve this we can use Export-Package, but it may complicate things as we don’t want to have the classes inlined in the bundle [inlined means here *.class files taken out of JAR and put in the bundle’]. That’s why we’re using little documented feature of the maven-bundle-plugin called <_exportcontents> – it will place all the sub-packages of given packages in exported packages section in MANIFEST file.

Another thing worth mentioning is the way the Hibernate dependency is declared in POM dependencies part. We manually exlude one of its transitive dependencies – commons-logging, as we will be using this dependency from FUSE ESB’s bundles. This reduces the final size of the resulting bundle. Btw, I’m pretty sure that it is possible to make this bundle even smaller..

osgi-hibernate-mysql-test module

Now, let’s prepare a sample application that will use of the wrapper bundle. We’ll use MySQL table which could like this:

 CREATE TABLE IF NOT EXISTS `honey` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(250) default NULL,
  `taste` varchar(250) default NULL,
  PRIMARY KEY  (`id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

What we need is POJO representation of the honey table, Hibernate configuration and the code that will make use of it.

The project structure will look like this:

│   pom.xml
│
└───src
    ├───main
    │   ├───java
    │   │   └───com
    │   │       └───lukaszbaran
    │   │           └───simpleosgi
    │   │               └───db
    │   │                   └───test
    │   │                       ├───entities
    │   │                       │       Honey.java
    │   │                       │
    │   │                       └───osgi
    │   │                               Activator.java
    │   │                               BundleUtils.java
    │   │                               HibernateApplication.java
    │   │
    │   └───resources
    │           hibernate.cfg.xml
    │           Honey.hbm.xml
    │           log4j.properties
    │
    └───test
        └───java

The POM file for the project will be really simple:

<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>
	<parent>
		<groupId>com.lukaszbaran.simpleosgi.db</groupId>
		<artifactId>parent-pom</artifactId>
		<version>1.0</version>
		<relativePath>../pom.xml</relativePath>
	</parent>
	<groupId>com.lukaszbaran.simpleosgi.db</groupId>
	<artifactId>osgi-hibernate-mysql-test</artifactId>
	<packaging>bundle</packaging>
	<version>1.0</version>
	<name>osgi-hibernate-mysql-test</name>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<version>1.4.3</version>
				<configuration>
					<instructions>
						<manifestLocation>META-INF</manifestLocation>
						<Import-Package>
							org.osgi.framework,
							org.hibernate,
							org.hibernate.cfg,
							org.hibernate.classic,
							javax.*,
							org.w3c.dom,
							org.xml.sax,
							org.apache.log4j
						</Import-Package>
						<Private-Package>
							com.lukaszbaran.simpleosgi.db.test.osgi.*
						</Private-Package>
						<Export-Package>
							com.lukaszbaran.simpleosgi.db.test.entities.*
						</Export-Package>
						<Bundle-Activator>
							com.lukaszbaran.simpleosgi.db.test.osgi.Activator
						</Bundle-Activator>
						<DynamicImport-Package>
							org.hibernate.proxy.*
						</DynamicImport-Package>
						<Require-Bundle>
							com.lukaszbaran.simpleosgi.db.osgi-hibernate-classes
						</Require-Bundle>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.2.6.ga</version>
		</dependency>
		<dependency>
			<groupId>org.apache.felix</groupId>
			<artifactId>org.osgi.core</artifactId>
			<version>1.0.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
	</dependencies>
</project>

The configuration of Bundle plugin may seem a little bit complicated but in fact it’s just a compilation of previous tutorials. We’re declaring that we require our wrapper bundle named: com.lukaszbaran.simpleosgi.db.osgi-hibernate-classes. The only package exported from this bundle is com.lukaszbaran.simpleosgi.db.test.entities – it is where we have our Honey POJO.

This POJO looks like this (it’s really nihil novum sub sole):

package com.lukaszbaran.simpleosgi.db.test.entities;
public class Honey {
	private Integer id;
	private String name;
	private String taste;
 	public Honey() {}
 
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getTaste() {
		return taste;
	}

	public void setTaste(String taste) {
		this.taste = taste;
	}
	
	@Override
	public String toString() {
		return "id=" + getId() + " \tname=" + getName() + " \ttaste=" + getTaste();
	}
}

The Hibernate mapping (Honey.hbm.xml):

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
	<class name="com.lukaszbaran.simpleosgi.db.test.entities.Honey" table="honey">
		<id name="id" column="id" type="java.lang.Integer">
			<generator class="increment"/>
		</id>
		<property name="name" column="name" type="java.lang.String"/>
		<property name="taste" column="taste" type="java.lang.String"/>
	</class>
</hibernate-mapping>

hibernate.cfg.xml file:

<?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>
		<property name="hibernate.connection.driver_class">
			com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">
			jdbc:mysql://localhost/firsthibernate</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">password</property>
		<property name="hibernate.connection.pool_size">10</property>
		<property name="show_sql">true</property>
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.hbm2ddl.auto">update</property>
	</session-factory>
</hibernate-configuration>

Eventually, we have three Java classes that form our application:

Activator.java this class should only store reference to the bundle in BundleUtils instance, however, I’ve decided to run the test method here:

package com.lukaszbaran.simpleosgi.db.test.osgi;
import org.apache.log4j.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
	private static final Logger LOGGER = Logger.getLogger(Activator.class);
	public void start(BundleContext arg0) throws Exception {
		LOGGER.info("Activator start() START");
		
		// because we need to access to the current bundle elsewhere
		if (arg0 != null) {
			BundleUtils.getInstance().setBundle(arg0.getBundle());
		}

		// perform some test connection
		HibernateApplication app = new HibernateApplication();
		app.test();
		LOGGER.info("Activator start() END");
	}
	public void stop(BundleContext arg0) throws Exception {
		LOGGER.info("Activator stop()");
	}
}

HibernateApplication.java configures Hibernate library using the config files that are embedded in the bundle and it invokes simple database access test:

package com.lukaszbaran.simpleosgi.db.test.osgi;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.lukaszbaran.simpleosgi.db.test.entities.Honey;
public class HibernateApplication {
	private static final Logger LOGGER = Logger.getLogger(HibernateApplication.class);
	public HibernateApplication() {	}

	@SuppressWarnings("unchecked")
	public void test() throws Exception {
		LOGGER.info("Application test() START");
		Session session = null;
		try {
			Configuration cfg = new Configuration();
			cfg.configure(BundleUtils.getInstance().loadResourceURL("/hibernate.cfg.xml"));
			cfg.addDocument(BundleUtils.getInstance().loadResourceXML("/Honey.hbm.xml"));
			SessionFactory sessionFactory = cfg.buildSessionFactory();
			session = sessionFactory.openSession();
			List<Honey> list = session.createCriteria(Honey.class).list();
			for (Iterator<Honey> iter = list.iterator(); iter.hasNext();) {
				Honey element = iter.next();
				LOGGER.debug(element);
			}
			session.close();
		} catch (Exception bhe) {
			LOGGER.error("Exception caught: ", bhe);
			throw bhe;
		} 
	}
}

BundleUtils.java is an ugly singleton class (it really should be done other way as I guess it is against the notion of OSGi) but this code was not the most important part of the show. We only needed to store a reference to a bundle somewhere. Besides that, the class provides methods to access bundle resources:

package com.lukaszbaran.simpleosgi.db.test.osgi;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class BundleUtils {
	private static BundleUtils instance = null; 
	private Bundle bundle;
        private final DocumentBuilder builder;
	private BundleUtils() {
	    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	    factory.setNamespaceAware(true);
	    try {
	        builder = factory.newDocumentBuilder();
	    } catch (ParserConfigurationException ex) {
	    	throw new RuntimeException("Unable to instantiate DocumentBuilder.", ex);
	    }		
	}
	public static synchronized BundleUtils getInstance() {
		if (instance == null)
			instance = new BundleUtils();
		return instance;
	}
	public Bundle getBundle() {
		return bundle;
	}
	public void setBundle(Bundle bundle) {
		this.bundle = bundle;
	}
	public Document loadResourceXML(final String resourceName) {
	    URL url = loadResourceURL(resourceName);
		try {
			InputStream is = url.openStream();
			return builder.parse(is);
		} catch (SAXException e) {
	    	throw new RuntimeException("Unable to parse resource.", e);
		} catch (IOException e) {
	    	throw new RuntimeException("IO exception while parsing resource.", e);
		}
	}
	public URL loadResourceURL(final String resourceName) {
	    URL url = null;
		if (bundle == null) { 
			url = this.getClass().getResource(resourceName);
		} else {
			url = bundle.getResource(resourceName);
		}
		if (url == null) {
			throw new RuntimeException("Unable to access resource.");
		}
		return url;
	}		
}

osgi-hibernate.zip contains all the source code presented here.

Summary

Of course, you can now build those two bundles and deploy them into FUSE ESB container (I guess it would be better to start with deploying Hibernate wrapper bundle in the first place). If your MySQL database is properly configured and if there was anything in the honey table, you would see some results in data/log/servicemix.log file.