Showing posts with label dataSource. Show all posts
Showing posts with label dataSource. Show all posts

2010-04-16

Never edit icky JBoss XML files again!

Do you have a JBoss application server? Do you have configuration files in that server that need to be edited or changed periodically? Do you have an allergy to XML?

Have I got a solution for you!

JBoss has the amazing ability to load *.properties files from any location (on the file system or on the internet) as part of its start up routine. So you can set properties in a simple properties file instead of an icky XML file.

NOTE: I'll refer to the directory you have installed JBoss into as $JBOSS_HOME you may have your JBoss server installed in /opt/jboss or /usr/local/jboss for example. It doesn't matter.

NOTE: I'll assume your JBoss is set up to load the "default" server directory. If it isn't then I think you are smart enough to figure out what to do on your own.



  1. Stop the JBoss server

  2. open the file $JBOSS_HOME/server/default/deploy/properties-service.xml in your favorite text editor.

  3. Find the tag
    <mbean code="org.jboss.varia.property.SystemPropertiesService" 
    name="jboss:type=Service,name=SystemProperties">

  4. Add this tag:
    <attribute name="URLList">
    /etc/jboss/system.properties
    </attribute>


  5. Comment out or delete any other instances of the <attribute name="URLList"> ... </attribute> tag



Great! Now when we start up the JBoss server again it will read the file /etc/jboss/system.properties and set its properties from there. But, wait... the file doesn't exist yet. If I start my JBoss server and that file isn't easily readable it will crash.

So let's create the directory...
$ sudo mkdir -p /etc/jboss

... and the file ...
$ sudo touch /etc/jboss/system.properties

... now we can restart JBoss safely.

We don't get much benefit yet though. Nothing in JBoss is using that file. So let's take a database-ds.xml file and configure it to use system.properties for its connector-url, user-name, and password.

Assuming you have a file like $JBOSS_HOME/server/default/deploy/database-ds.xml you can edit it to look like:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MyDatabaseDS</jndi-name>

<connection-url>${MyDatabaseDS.connection-url}</connection-url>
<driver-class>${MyDatabaseDS.driver-class}</driver-class>
<user-name>${MyDatabaseDS.user-name}</user-name>
<password>${MyDatabaseDS.password}</password>

<min-pool-size>10</min-pool-size>
<max-pool-size>20</max-pool-size>
<prepared-statement-cache-size>10</prepared-statement-cache-size>
</local-tx-datasource>
</datasources>


Now edit /etc/jboss/system.properties to hold those values... it should look like this

# config for database-ds.xml
MyDatabaseDS.connection-url=jdbc:postgresql://localhost:5432/database
MyDatabaseDS.driver-class=org.postgresql.Driver
MyDatabaseDS.user-name=username
MyDatabaseDS.password=password
# this example is for postgresql but you could substitute any database.


... when you start up JBoss it will read the /etc/jboss/system.properties file and when it looks at database-ds.xml it will see the ${variable} values and substitute the values you set in system.properties for the ${variable}. If a ${variable} is not present, there will be no substitution... so be sure that every time you use a variable you set its value somewhere.

You can also set system wide system properties this way too. Commonly on servers that I work with the unix host name has nothing to do with the hostname being served. So I commonly set:

server.host=server.example.com


For use in my Grails applications which I then read in Config.groovy like this:

grails.serverURL = "https://${System.getProperty('server.host')}/${appName}"

... but that is another story ...

2007-11-27

Grails Datasource, legacy database, and you

Any one out there trying to work with Groovy, Grails, and legacy databases?

Well, I am and I thought I'd share with you my final dataSource configuration. I'm using a legacy database that drove an Apache + mod_perl web site that had a MySQL 3.x database. The Groovy/Grails project I'm working on will interact with that data (right now as a read-only service) and here's the final dataSource definition I ended up using for our first beta.


import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
/**
* This project is driven off of Legacy data.
* Use update to prevent wiping old tables...
* much of the data is accessed using JPA classes generated by
* the Hibernate3 reverse engineer tool.
********************************************************************/
dataSource {
configClass = GrailsAnnotationConfiguration.class
dbCreate = "update"
dialect= org.hibernate.dialect.MySQLMyISAMDialect // or perhaps MySQL5Dialect
pooled = false
}
environments {
development {
dataSource {
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/legacy?zeroDateTimeBehavior=convertToNull"
username = "legacy"
password = "legacy"
}
}
test {
dataSource {
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/legacy?zeroDateTimeBehavior=convertToNull"
username = "legacy"
password = "legacy"
}
}
production {
dataSource {
jndiName = "java:/LegacyDS"
}
}
}


The LAMP stack was upgraded to use MySQL 5 recently so we can set up our new projects using the setting dialect= org.hibernate.dialect.MySQLInnoDBDialect which will give us the ability to use actual foreign key relationships. That's a big deal if you are a LAMP developer. I suppose that in short order I will be a Grails, Linux, Apache, MySQL developer... a GLAM developer... ah... no... lets not call it that.

BTW: I deploy to a JBoss Application server in production which manages the DataSources in a legacy-ds.xml file under /usr/local/jboss/server/default/deploy that's why my production dataSource uses the jndi lookup.