Accessing custom Properties from JBoss AS

Posted by Martin Cabrera on October 07, 2011

Hi everyone !

I have this issue / trouble several times. I would love share this tips with the JBoss coomunity … particularity JBoss Application Server (AS) developers.

Problem:

I have a scenario to access certain key values from a config file. I need Access to this properties file from a Java application (WAR or JAR) deployed in a JBoss AS

Solutions

1- Hard Code the path (no please !!)

Hard Code the path and create a Properties instance.

InputStream inStream = new FileInputStream(PATH_CONFIG+"config.properties");
Properties instance = new Properties();
instance.load(inStream);
//access to a property
String value = instance.getProperty(key);

2- Using JBoss System Properties (almost)

Avoid to Hard Code … use a tool from JBoss. System.getProperty()

JBoss allows access to a standard set of properties. For instance: jboss home dir (“jboss.server.home.dir). Here I share some piece of code to make an instance of this properties file.

String path = System.getProperty("jboss.server.home.dir")+"/conf/config.properties";
InputStream inStream = new FileInputStream(path);
Properties instance = new Properties();
instance.load(inStream);
//access to a property
String value = instance.getProperty(key);

3- Using Resource bundle (the best !)

JBoss AS add to the classpath a lot of folders and jars. One of them is the “config” folder into the server domain. eg. “server/default/conf”

ResourceBundle objects contain an array of key-value pairs. You specify the key, which must be a String, when you want to retrieve the value from the ResourceBundle. The value is the locale-specific object.

When you create a ResourceBundle this properties file must be in the classpath.

Then we could:

ResourceBundle instance = ResourceBundle.getBundle("project.config");
//access to a property
String value = instance.getString(key);

In this example the file “config.properties” must be inside a “project” folder declared in the classpath, for instance: “config”

That’s all folk !

Auditing, History of database modifications with Hibernate – Envers Solution !

Posted by Martin Cabrera on October 27, 2010

hibernate-logo

Envers is one of the Hibernate’s project sponsored by Redhat. Works with Hibernate and Hibernate Entity Manager.

Aims to enable easy auditing of persistent classes. For each audited entity you must annotate your persistent clases with @Audited, a table will be created, which will hold the history of changes made to the entity.

The idea is very similar to CVS or Subersion. Each transaction with updates, deletes or inserts made in the database with hibernate generate a new revision number. One transaction is one revision.

Envers provide a simple way to retrive your data of a revision using: revision number, date, queries with min and max function between others.

You can use Envers wherever Hibernate works: standalone, inside JBoss AS, with JBoss Seam or Spring.

It’s very easy …

@Entity
@Audited
public class Usuario {
public enum Rol{
EMPRESA, ADMINISTRADOR,MESA_ENTRADA;
}
private Long id;
private String usuario;
private String contrasenia;
private Rol rol;
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Entity @Audited
public class User {
	private Long id;

        @Id @GeneratedValue
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }

        // other fields and methods
        ...
}

Envers configuration

When configuring your Hibernate (persistence.xml if you are using JPA, hibernate.cfg.xml or other if you are using Hibernate directly), add the following event listeners:

<persistence-unit ...>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>...</class>
<properties>
   <property name="hibernate.dialect" ... />
   <!-- other hibernate properties -->

   <property name="hibernate.ejb.event.post-insert"
             value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-update"
             value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-delete"
             value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.pre-collection-update"
             value="org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.pre-collection-remove"
             value="org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-collection-recreate"
             value="org.hibernate.envers.event.AuditEventListener" />
</properties>
</persistence-unit>

Then, annotate your persistent class with @Audited (like the User example)

And that’s it!

Queries

Find audited data

You can access the audit (history) of an entity using the AuditReader interface, which you can obtain when having an open EntityManager.

AuditReader reader = AuditReaderFactory.get(entityManager); 
User oldUser = reader.find(User.class, userId, revision)

Search a revision number

the whole documentation is in the Web site:  http://docs.jboss.org/envers/docs/index.html#queries

To ilustrate one example I show the way to search the max number revision of one Entity audited.

Number revision = (Number) reader.createQuery().forRevisionsOfEntity(User.class, false, true)
.addProjection(AuditEntity.revisionNumber().max())
.add(AuditEntity.id().eq(userId))
.getSingleResult();

We use Envers in a few projects. Works fine and very quickly, we recomended … no dubt ! Envers

Web site: www.jboss.org/envers

Envers documentation: http://docs.jboss.org/envers/docs/index.html