« Posts tagged configuration

Configuring Data Sources, JBoss 7

Yep it’s gonna be a big year for JBoss AS 7

This will be the first in a series I’ll be writing on JBoss’ new application server version 7. Lately I’ve been playing around with JBoss AS 7 recently, and all I can say is.. !@#%, NICE! I downloaded 7.0 with the expectation that it would honor a lot of the previous version’s overall approach and layout. I was in for a BIG surprise. It comes off as a total rewrite, leveraging a lot of the latest and greatest technologies and frameworks – things like Weld (an implementation of the context and dependency injection spec – JSR-299), OSGi (the Open Services Gateway initiative framework for the uninitiated), Hibernate, and RESTeasy.

I’ll say the guys over at JBoss certainly delivered. Before, server start up times could take a respectable 30 seconds to a minute or more depending on your deployment structure and dependencies. Now you ask? Less time than my 15 second ant build script! Right now I’m clocking 14 second from cold to deployed on my smaller sized application. With AS 5, the same deployment was taking something like a minute. Hat’s off guys, you all at JBoss really did some work!

The first thing and arguable the most difficult thing you’ll want to do is set up the data source for your deployment.

Configuring the Data Source

Before we had to configure out postgres-ds.xml file with all the data source metadata required to configure out application. The process now isn’t as straight forward – there are three ways to do it, two if you don’t count using the really nice console manager it ships with. I should mention that now there are 2 types of configuration setups 1) domain and 2) standalone. Standalone is the model we’re most familiar with – a single instance acting as a single server. Domain on the other hand is geared for a clustered style of deployment – although its way more flexible than that. More on this in another article. For the sake of simplicity, lets start with the standalone type.

Place the jdbc driver

There are 2 ways to do this. The first is really straight forwards – just stick your jdbc jar file in the deployment folder indicated in the configuration file:

jboss-7.0.0.GAstandaloneconfigurationstandalone.xml

Relevant contents:

<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.0">

	<deployment-scanner name="default" 
		scan-enabled="true" scan-interval="5000" 
		deployment-timeout="60"
		relative-to="jboss.server.base.dir" 
		path="deployments" />

</subsystem>

Stick your jdbc jar file in here, and JBoss will automatically configure your standalone.xml file for you. BTW, this deployment-scanner entry maps the location of the deployments directory:

jboss-7.0.0.GAstandalonedeployments

Where jboss.server.base.dir points to the “standalone” directory and path maps the name of the deploy folder “deployments”.

The second way is a more complex and so requires a little bit more legwork. JBoss has completely changed its class loading strategy, and if you’ve ever worked with Maven repositories it might feel very familiar. Essentially jboss’ modules folder is where all the jars that are used by the jboss server live. By separating them into a separate classpath, you won’t run into weird classpath errors when there are competing jar files/versions deployed by your application. This problem exposed itself in earlier versions of jboss – in particular with the xml jars. If you had a mixed case of xml libraries, jboss might have been using an older version that could override your application’s newer version – hard to track down if you don’t know where to look. Anyway, these jar files are organized by psuedo packages – just like maven repositories except the final folder is called main. Each module jar file must be placed there and be paired with corresponding a module.xml file. For example you’d want to create a folder in your install like this:

jboss-7.0.0.GAmodulesorgpostgresqlmain

Here is an example of module.xml:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.postgresql">
  <resources>
    <resource-root path="postgresql-9.0-801.jdbc4.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
    <module name="javax.transaction.api"/>
  </dependencies>
</module>

You’ll want to map the name of the jdbc driver, as well as the name of the module name here – we’re going to map it to the configuration next. Once this is squared away, we’ll want to configure the standalone.xml file:

jboss-7.0.0.GAstandaloneconfiguration

Map and Configure

In standalone.xml, you’ll want to look for the <subsystem xmlns=”urn:jboss:domain:datasources:1.0″> node and add a shiny new configuration like this:

<subsystem xmlns="urn:jboss:domain:datasources:1.0">
	<datasources>
			<datasource jndi-name="java:jboss/DefaultDS" enabled="true" 
				jta="true" use-java-context="true" use-ccm="true"
				pool-name="postgresDS" >
			<connection-url>
				jdbc:postgresql://localhost:5432/database?charSet=UTF-8
			</connection-url>
			<driver>
				org.postgresql
			</driver>
			<transaction-isolation>
				TRANSACTION_READ_COMMITTED
			</transaction-isolation>
			<pool>
				<min-pool-size>
					10
				</min-pool-size>
				<max-pool-size>
					100
				</max-pool-size>
				<prefill>
					true
				</prefill>
				<use-strict-min>
					false
				</use-strict-min>
				<flush-strategy>
					FailingConnectionOnly
				</flush-strategy>
			</pool>
			<security>
				<user-name>
					username
				</user-name>
				<password>
					password
				</password>
				</security>
			<statement>
				<prepared-statement-cache-size>
					32
				</prepared-statement-cache-size>
			</statement>
		</datasource>
		<drivers>
			<driver name="org.postgresql" module="org.postgresql">
				<datasource-class>
					org.postgresql.Driver
				</datasource-class>
			</driver>
		</drivers>
	</datasources>
</subsystem>

Pay attention to:

	<driver>
		org.postgresql
	</driver>

Note: you can set this to the jdbc driver file name if you’re using the deploy approach. In fact, jboss will be more than happy to write the driver configuration for you if you deploy the driver from the deploy directory.

This entry maps to the driver configured directly below to the driver name configured by :

	<driver name="org.postgresql" module="org.postgresql">
		<xa-datasource-class>
			org.postgresql.Driver
		</xa-datasource-class>
	</driver>

The name property maps the driver to the configuration, and the module property maps to the module we laid out in the first step. I’ll point out that it seems that you need to use a transaction aware data source. I think you’re supposed to be able to use the node </datasource-class> with the regular driver class but when I tried this, I got xml parsing errors – it doesn’t seem to think “datasource-class” is a legal element.

You can call on the data source file through the jndi handle configured on the datasource node: jndi-name=”java:jboss/DefaultDS”. The rest of the properties and nodes configure various settings for your datasource, and if you’ve worked with them before you will probably be familiar with them already. If you need a refresher (like me) you can also look through all the JBoss user guide documentation.

References:
JBoss Wiki on Datasource configuration
JBoss user guide documentation
JBoss Wiki Getting Started Guide
JBoss Getting Started Admin Guide

The conf directory, JBoss v5.x

Configure what you need

So you’re ready to configure some JBoss files? Great, lets have a look at the conf directory. The jboss/server/<configured instance>/conf directory is where you’ll find the majority of the configuration files for your jboss instance. For most deployments, the majority of these folders and files will remain untouched as they default to usable configurations. In this article we’ll go over the more practical configurable files, while leaving the really low level configurations alone.

`-- conf
    |-- bootstrap/
    |--|-- bindingservice.bean
    |   `-- META-INF
    |   |    `-- bindings-jboss-beans.xml *
    |   |-- aop.xml
    |   |-- classloader.xml
    |   |-- deployers.xml
    |   |-- jmx.xml
    |   |-- logging.xml
    |   |-- profile.xml *
    |   `-- vfs.xml
    |-- props
    |   |-- jbossws-roles.properties
    |   |-- jbossws-users.properties
    |   |-- jmx-console-roles.properties
    |   `-- jmx-console-users.properties
    |-- xmdesc
    |   |-- AttributePersistenceService-xmbean.xml
    |   |-- ClientUserTransaction-xmbean.xml
    |   |-- JNDIView-xmbean.xml
    |   |-- Log4jService-xmbean.xml
    |   |-- NamingBean-xmbean.xml
    |   |-- NamingProviderURLWriter-xmbean.xml
    |   `-- NamingService-xmbean.xml
    |-- bootstrap.xml
    |-- jacorb.properties
    |-- java.policy
    |-- jax-ws-catalog.xml
    |-- jboss-log4j.xml
    |-- jboss-service.xml
    |-- jbossjta-properties.xml
    |-- jndi.properties
    |-- login-config.xml
    |-- standardjboss.xml
    `-- standardjbosscmp-jdbc.xml

For starters, the bootstrap.xml file lets you configure which microcontainer deployments are loaded on boot. The ones we want to pay special attention to are profile.xml and conf/bindingservice.beans’s bindings-jboss-beans.xml (marked with an asterisk in the layout diagram) The other files are geared for low level configurations. For example – aop.xml configured how aop is implemented in jboss, deployers.xml configures jboss’ classloaders, and vfs.xml tells jboss what lib folders to load jars from.

External deployments

If you open up profile.xml, you’ll see a set of configurations that describe what kind of deployers are used for the profile object management service. Most of the contents deal with Jboss’ innards, but worthy of reviewing is the “applicationURIs” property. It’s actually a list of java.net.URI urls, and you can add elements to this list in order to configure Jboss so that it looks in to external deployment directories in addition to the defauls deploy directory. More detail is described in the related article “External deploy directories in JBoss 5.1”.

Port Bindings

Before Jboss 5, you would have to manually go in and change each port into its own numberspace. There were a bunch of places where these ports would need to be updated (for things like the naming and rmi services) across a slew of files scattered all over the place. In Jboss 5, if you open up bindings-jboss-beans.xml, you’ll find a means of binding multiple jboss instances across different ports in a single centralized location. Out of the box, Jboss ships with 4 sets of port configurations. Each configuration set reserves a set of ports for JBoss’ use. If you trail through each of these port configurations, you’ll notice the sets are offset by increments of 100. So for example the first configuration reserves 1099 for the NamingServer, while the second set reserves 1199, and the third set uses 1299 and so on. This functionality is particularly useful when you want Jboss to run on a single IP address. Given a choice though, I would opt for using a single IP per Jboss instance. It’s nice to have this option though, in case multiple IPs is not an option.

We can get an idea of how JBoss configures these binding sets from the snippets below – both are straight out of the bindings-jboss-beans.xml file:

<!-- Provides management tools -->
<bean name="ServiceBindingManagementObject" 
  class="org.jboss.services.binding.managed.ServiceBindingManagementObject">

  <constructor>
     <!-- The name of the set of bindings to use for this server -->
     <parameter>${jboss.service.binding.set:ports-default}</parameter>

     <!--  The binding sets -->
     <parameter>
	 <set>
	    <inject bean="PortsDefaultBindings"/>
	    <inject bean="Ports01Bindings"/>
	    <inject bean="Ports02Bindings"/>
	    <inject bean="Ports03Bindings"/>
	 </set>
     </parameter>

     <!-- Base binding metadata used to create bindings for each set -->
     <parameter><inject bean="StandardBindings"/></parameter>

  </constructor>
</bean>

...

<!-- bindings are obtained by taking the base bindings and adding offsets  -->
<bean name="Ports01Bindings"  
	class="org.jboss.services.binding.impl.ServiceBindingSet">
	<constructor>
	<!--  The name of the set -->
		<parameter>ports-01</parameter>
	<!-- Default host name -->
		<parameter>${jboss.bind.address}</parameter>
	<!-- The port offset -->
		<parameter>100</parameter>
	<!-- Bindings to which the "offset by X" approach can't be applied -->
		<parameter><null/></parameter>
	</constructor>
</bean>

If you run Jboss without a ports configuration, it will use the default port settings. If you want to use a specific port configuration, all you need to do is add the startup param to the run.sh script used to invoke jboss: “-Djboss.service.binding.set=ports-01”. This param selects which port config to use, and likewise can be used to use any of the available port bindings found in bindings-jboss-beans.xml.

The props folder – default UsersRolesLoginModule properties for jmx-console security

If you make use of jmx-console’s default UsersRolesLoginModule JAAS security domain configuration, you’ll find that the user and role properties are stored in this “props” folder. More on securing the jmx console can be found here. You can also opt to use a different security module, by defining a different login module in login-config.xml. More on this in a few paragraphs.

The xmdesc folder – mbean descriptors

This folder contains all the descriptors used for the major mbeans described in the jboss-service.xml. Not all the possible mbeans have been converted over to the new bootstrapping style format, so these legacy descriptors close the gap to allow existing mbean services to continue to work.

Logging with jboss-log4j.xml

This piece allows you to configure the logging for the entire instance. If you’re familiar with log4j, you’ll know right off the bat how to configure the logging. Out of the box Jboss ships with console output enabled. For production level environments though, we’ll want that disabled as console logging always takes up unnecessary system resources. You are able to control smtp, console, file, jms, and file based logging with levels (DEBUG, INFO, WARN, ERROR, FATAL etc) and by category (com.yourpackage.class or com.yourpackage). Asynchronous appenders allow you to configure logging that gets piped to more than one target. Learn mroe about how to configure this from Apache’s Log4J’s project website. A basic log4j configuration can be found in the example below:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" 
      debug="false">
   <!-- A time/date based rolling appender -->
      <appender class="org.jboss.logging.appender.DailyRollingFileAppender"
        name="FILE">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="File" value="${jboss.server.log.dir}/server.log"/>
      <param name="Append" value="true"/>
       
      <!-- Rollover at midnight each day -->
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>

      <layout class="org.apache.log4j.PatternLayout">
         <!-- Default pattern: Date Priority [Category] (Thread) Messagen -->
         <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
      </layout>
   </appender>

   <root>
	<priority value="${jboss.server.log.threshold}"/>
	<appender-ref ref="FILE"/>
   </root>
</log>

JAAS/Security Domains with login-config.xml

This file allows you to configure security domain with JAAS for your applications. You have a number of login modules to choose from, notably the DatabaseServerLoginModule. This module allows you to hook in a set of users and roles query into a datasource to validate authentication credentials and allow access to your application. In a default install, Jboss will have example configurations where users and roles are also stored in the props directory and accessed via the UsersRolesLoginModule.

An example JAAS database login module configuration in login-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
  <application-policy xmlns="urn:jboss:security-beans:1.0" name="loginForm">
    <authentication>
      <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
        flag="required">
        <!--  BASE64 also possible -->
        <module-option name="hashAlgorithm">MD5</module-option> 
        <module-option name="unauthenticatedIdentity">guest</module-option>
        <module-option name="dsJndiName">java:/DefaultDS</module-option>
        <module-option name="principalsQuery">
        	SELECT password FROM User WHERE username=?
        </module-option>
        <module-option name="rolesQuery">
        	SELECT role, 'Roles' 
        	FROM UserRoles, User 
        	WHERE User.username=? 
        		AND User.id = UserRoles.user_id
        </module-option>
      </login-module>
    </authentication>
  </application-policy>
</deployment>

In order for this configuration to work we’ll need to also add security domains to our web application’s web.xml as well as a the Jboss only jboss-web.xml deployment descriptor. More on how to configure this can be fond in Jboss’ server manual, section 9.6.4.

The remaining files

The last remaining files cover various integration configurations, and delve into Jboss’ low level implementation. One example is the java.policy file which configures your instance’s security policy on the jvm level. You may constrain permissions to allow strictly reading across the board or some custom mix of read and write, and by class. More information can be found on Jboss Web’s security manager page. For the uninitiated, Jboss Web is the integrated version of Tomcat 6 that deploys with JBoss as a deployable service.

The jbossjta-properties.xml file configures the Jboss transaction server’s default behavior. The jax-ws-catalog.xml maps xml metadata for use with jax-ws webservices, as specified by the Oasis XML Catalog spec. The jndi.properties file maps classes used by Jboss’ naming server. The jacorb.properties file configures JacORB (Java implementation of OMG’s Corba standard) for use with Jboss.

Finally, the standardjbosscmp.xml config defines how various types of enterprise java beans are configured during regular use, while standardjbosscmp-jdbc.xml configures specific persistence dialects relating to type mappings so that datasource files can communicate correctly with different database vendors. In your datasource file you can add a type element to specify which of these defined types jboss should use:

<?xml version="1.0" encoding="UTF-8"?>  
<datasources>   
     <local-tx-datasource> 
        <jndi-name>DefaultDS</jndi-name> 
        <connection-url>jdbc:postgresql://localhost:5432/db</connection-url> 
        <driver-class>org.postgresql.Driver</driver-class> 
         <user-name>user</user-name>   
         <password>password</password> 
          <metadata> 
               <type-mapping>PostgreSQL</type-mapping> 
          </metadata>          
     </local-tx-datasource> 
</datasources>

The recap

Once you’ve gone over these configuration files, you’ll have seen with some depth part of what Jboss is capable of. As mentioned earlier, you wont want to muck around with most of these configurations unless you’re working on Jboss server code itself or unless you want to tweak the server’s behavior. The most commonly edited files end up being bindings-jboss-beans.xml (multiple port bindings), profile.xml (external deploy directories), jboss-log4j.xml (logging), login-config.xml (security domains) and java.policy (jvm level security permissions). With these basics you can be well off into configuring Jboss for whatever needs you need to fill.

Resources:
Securing the JMX Console
JBoss App server Quick Tour
JBoss Web manual
Oasis XML Catalog project

Virtual hosting with Jboss 5.1

How do I map a web application to a url in jboss?

If you have multiple web apps deployed in a single jboss instance, you’ll probably want to figure out an effective way to tell them apart when you try to access them from a browser. On startup jboss can be configured to bind to a single url which will act as the default host for all the deployed applications. You can then set up a separate context for each web app you are running. If they’re totally separate applications though, it might not make sense to use a single url and break them out by context. In Jboss you can set up virtual hosts to solve this dilemma. Here’s how to set this up:

WEB-INF/jboss-web.xml

In your web application you’ll want to add an xml file named “jboss-web.xml” to your WEB-INF folder. This is the file that’s going to map both the web application’s context and host in jboss.

<jboss-web>
    <context-root>/</context-root>
    <virtual-host>www.first-application.com</virtual-host>
</jboss-web>

This configuration sets the application’s context to “/” (essentially the root of the default domain), and it also maps the virtual host configuration to “www.first-application.com”. Note that it wont matter if you deploy this configuration from within an ear (embedded war file) or as a standalone war file, as only wars are meant to respond to web requests. Let’s also add the second configuration to the other war file’s WEB-INF/jboss-web.xml:

<jboss-web>
    <context-root>/</context-root>
    <virtual-host>www.second-application.com</virtual-host>
</jboss-web>

Next, we’ll need to add the virtual host configurations to jboss’ server.xml.

jbossweb.sar/server.xml

Now we need to edit jboss’ server.xml file, adding the virtual host mappings:

<Server>
   <Service name="jboss.web"
      className="org.jboss.web.tomcat.tc5.StandardService">
       
      <!-- A HTTP/1.1 Connector on port 8080 -->
      <Connector port="8080" address="${jboss.bind.address}"
                 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                 enableLookups="false" redirectPort="8443" acceptCount="100"
                 connectionTimeout="20000" disableUploadTimeout="true"/>

      <Engine name="jboss.web" defaultHost="www.first-application.com">
         <Realm className="org.jboss.web.tomcat.security.JBossSecurityMgrRealm"
          certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping"
            />
         <Logger className="org.jboss.web.tomcat.Log4jLogger"
                 verbosityLevel="WARNING"
                 category="org.jboss.web.localhost.Engine"/>

            <Host name="www.first-application.com" autoDeploy="false"
                  deployOnStartup="false" deployXML="false">
                <Alias>dev.first-application.com</Alias>
                <Alias>qa.first-application.com</Alias>   
                <Alias>test.first-application.com</Alias>    
                <Valve className="org.apache.catalina.valves.AccessLogValve"
					   prefix="localhost_access_log." 
					   suffix=".log"
					   pattern="common" 
					   directory="${jboss.server.log.dir}" 
					   resolveHosts="false" />
            </Host>   

            <Host name="www.second-application.com" autoDeploy="false" 
                  deployOnStartup="false" deployXML="false">
                <Alias>dev.second-application.com</Alias>
                <Alias>qa.second-application.com</Alias>   
                <Alias>test.second-application.com</Alias>    

                <Valve className="org.apache.catalina.valves.AccessLogValve"
					   prefix="localhost_access_log." 
					   suffix=".log"
					   pattern="common" 
					   directory="${jboss.server.log.dir}" 
					   resolveHosts="false" />
            </Host>

      </Engine>
   </Service>
</Server>

Note the alias map other optional domains that jboss would listen for as aliases of the keyed domains “www.first-application.com” and “www.second-application.com”. All this means is jboss will redirect requests for processing to the respective web application’s whose virtual-host config maps to this host configs.

In order for all of this to work however, we need to make sure dns is set up to handle these domain requests. On a local development machine, you’ll want to edit your hosts file (on windows: c:/WINDOWS/System32/drivers/etc/hosts, on linux: /etc/hosts) and add these entries:

127.0.0.1		www.first-application.com
127.0.0.1		www.second-application.com

This way when you type in one of the domains into your browser, it’ll forward the request to jboss’ bound IP. likewise, if you have jboss bound to a specific domain name/IP on boot, you would have to map that domain/ip in your hosts file just like in the example above.

Now you should be able to fire up jboss, type in either domain into the browser, and have jboss redirect those requests to the corresponding deployed war file.

External deploy directories in JBoss

Why not use the default jboss deploy directory?

Out of the box, jboss has a bunch of .sar, .war, and .jar deployment artifacts as well as a bunch of xml files in the default deploy directory (whose path is “jboss-install-dir/server/configured-server-instance/deploy”). For the sake of being neat and cautious, I prefer to break out any deployment artifacts that are constantly in development to a separate external directory where I would never be able to “accidentally” delete all the other important configuration files required by jboss to run. Something like that never happened to me, but a friend. Yeah, a friend. About the only thing I feel ok with leaving in the default deploy directory are the “-ds” files that map the database configurations for the instance. These database settings rarely if ever change so it abides by the “deploy moving targets to an external directory” school of thought.

Ok, I want to deploy and external directory. How do I set it up?

Well, the answer depends on which version of JBoss you are running. In general, the process is twofold: first we’ll want to locate the deployment folder configuration and then add our own entry to the list of directories JBoss inspects for deployable artifacts. If we hardcode this location, we won’t need a second step. If we want this external directory to be parameterized though, we’ll need to make sure the edits we make to the configuration match the input parameter’s name for substitution.

JBoss 5.1

Open up the profile.xml file:

[root@bedrock ~]# vim /jboss-root/server/instance/conf/bootstrap/profile.xml

You’re going to want to add a line like the following:

<bean name="BootstrapProfileFactory" 
class="org.jboss.system.server.profileservice.repository.StaticProfileFactory">
...
<property name="applicationURIs">
	<list elementClass="java.net.URI">
		<value>${jboss.server.home.url}/deploy</value>
		<value>file:/c:/external/location/deploy/directory/path</value>
		<value>${external.deploy.dir}/deploy</value>
	</list>
</property>
...
</bean>

You’ll notice the two ant script like looking variables in the list. The first one ${jboss.server.home.url}, declares the JBoss server’s default deploy location. The other one ${external.deploy.dir}, is a parameterized version of an externalized deploy directory. If you use this second style, you’ll need to make sure to pass in a parameter in the format “-Dexternal.deploy.dir=file:/c:/external/location”. This will pass in the value so the substitution will provide a fully qualified URL to scan for deployments. Note, however if the parameterized version does not satisfy a reachable location, JBoss will continuously attempt to deploy that location if you have hot deploy and/or deployment scanner enabled (these services will attempt to periodically attempt to scan deployment directories for new deployments).

Save the file, and fire up jboss, and you’re good to go.