Archive for the ‘ recommended ’ Category

Setting up a private UDDI on JBoss

As part of the Service Oriented Architecture (SOA) that I’m implementing at work, I wanted to investigate setting up a private UDDI so that developers across the country could publish and find any core services. The first hit on Google when searching on the subject is Apache jUDDI, so I started to investigate that (since I love ASF). First thing I notice is that it’s a WAR file, but our platform here is based on ColdFusion, and the standalone installation used in the company couldn’t support implementing it. First thing that pops into my head, of course, is “Let’s look at my old friend, JBoss”.

jUUDI and JBoss Intro

After a quick install of JBoss, I drop in the jUDDI application and immediately run into configuration problems that I won’t bore you with now. However, as I start my research, I very quickly discover that jUDDI is integrated into JBoss! So at this point, the folks at JBoss go up a notch in my esteem.

I then drop the standard jUDDI application from JBoss and copy over the juddi-service.sar to my implemented server and fire it up. First thing I notice is that it’s looking for a JNDI datasource, which I had never set up before, but discover it’s quite simple.

Installing a MySQL UDDI Datastore

  1. Download and install MySQL
  2. Download the 0.9RC4 version of jUDDI
  3. Extract the jUDDI zip and look in the sql directory to get the script for setting up the juddi database
  4. Make sure you have the jboss-local-jdbc.rar package in your JBoss deploy directory
  5. Download the MySQL connector (mysql-connector-java-5.1.5-bin.jar) and put it in the server\lib directory
  6. Create a file named juddi-ds.xml in your deploy directory and create your JNDI datasource.
    Listing 1.1

    <datasources>
       <local-tx-datasource>
          <jndi-name>juddiDB</jndi-name>
          <connection-url>jdbc:mysql://{mysql server ip}:3306/juddi</connection-url>
          <driver-class>com.mysql.jdbc.Driver</driver-class>
          <user-name>{username}</user-name>
          <password>{password}</password>
          <min-pool-size>5</min-pool-size>
          <max-pool-size>20</max-pool-size>
       </local-tx-datasource>
    </datasources> 
  7. Open up the jboss\server\default\deploy\juddi-service.sar\juddi.war\WEB-INF\jboss-web.xml file and change the jndi-name property to refer to the name you just created
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <!DOCTYPE jboss-web PUBLIC
            "-//JBoss//DTD Web Application 2.3V2//EN"
        "http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd">
    
    <jboss-web>
        <context-root>juddi</context-root>
        <resource-ref>
            <res-ref-name>jdbc/juddiDB</res-ref-name>
            <jndi-name>java:/juddiDB</jndi-name>
        </resource-ref>
    </jboss-web>

Ok, so now I’ve got a database set up to store all of the UDDI information… now what? Let’s see if jUDDI started up correctly. I hit http://localhost/juddi and - SHAZAM! - it works: I get a standard “Welcome to JBoss JUDDI” screen. Now I try to publish a service to it. How do I do that?

Some more Googling gets me to the Eclipse Web Services Explorer, which is part of the Web Tools Platform. I install all of the packages and launch the explorer. I test a sample WSDL and it works great, so far so good. Then I try to publish a service to the UDDI and I start getting exceptions in the interface. I check the logs and see the following exceptions …

ERROR [JUDDIServlet] java.lang.IllegalStateException: Failed to load javax.xml.soap.MessageFactory: org.jboss.ws.core.soap.MessageFactoryImpl
ERROR [JUDDIServlet] A serious error has occured while assembling the SOAP Fault.

Back to Google I go and 30 minutes later I finally find some relevant discussions and possible resolutions. What it boils down to is you have to override the org.jboss.ws.core.soap.MessageFactoryImpl class with com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl.

How do you do this?

Implementing SOAP with Attachments API for Java (SAAJ)

Go to the SAAJ project site and download the latest SAAJ release. Extract the zip file and copy the two files in the lib directory…

  • saaj-api.jar
  • saaj-impl.jar

to your deploy\lib directory.

Open the jboss\server\default\deploy\properties-service.xml file and set some system properties.

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

    
    <attribute name="Properties">
      javax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
      javax.xml.soap.SOAPFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl
    </attribute>
</mbean>

Now restart JBoss and try to publish your service again via the Web Services Explorer (or whatever tool you want to use) and it should work.

ColdFusion on JBoss with Apache Proxy

I won’t go heavily into the reasons why you would want to use Apache as your proxy to JBoss, but I’ll give some popular ones here so you can see if any of the areas interest you.

  1. You want to run PHP and ColdFusion on the same server with minimal headaches
  2. You want to host multiple domains on your JBoss instance
  3. You need to use complex URI rewriting rules for incoming requests
  4. You need to run IIS and JBoss on the same server
  5. You just need a solid, lightweight web server

The reasons I chose to use Apache to act as the web server for my JBoss servers were 1 and 2. I eventually needed to do a little bit of 3. I temporarily had to do number 4, and how easily I have been able to do all of this led me to believe number 5.

Preparing JBoss

The only thing you need to change on JBoss to have Apache act as a proxy to it is ensure that is it not listening on port 80 (which you may have set if it was acting as your web server). Read step 5 in my standalone primer article for instructions on how to change your HTTP port if you haven’t done this before.

Install Apache

I downloaded version 2.0.58 which works just fine for my purposes. However, by the time you read this article, there may be a much better and/or feature-rich version of Apache available. Just download the version you feel best suits your purposes based on your needs.

Configure Apache

Find the ‘Listen’ section of in the \Apache\conf\httpd.conf file and specify the IP address and port on which Apache is listening.

Listen <server ip address>:80

Next, you need to tell Apache where to direct traffic coming in on port 80 on that IP address. For this, we use Virtual Hosts.

NameVirtualHost <server ip address>:80

Now that Apache is prepared to accept request for multiple domain names, we need to set up each of those domains using the <virtualhost> tag. All you need to specify is the ServerName property, which the the base URL of the domain, and the ProxyPass property which simply tells Apache where to redirect the original request.

If your JBoss server is internal only and not public facing, you’ll have to use the IP address from Apache since that’s the designator for it.

<virtualhost>
    ServerName www.orbwave.com
    ProxyPass / http://{jboss server IP}:8080/
</virtualhost>

<virtualhost>
    ServerName www.fusioncube.net
    ProxyPass / http://{jboss server IP}:8080/
</virtualhost>

If you have both Apache and JBoss sitting on your public web server, you’ll need to use the domain name instead of the IP address.

<virtualhost>
    ServerName www.orbwave.com
    ProxyPass / http://www.orbwave.com:8080/
</virtualhost>

<virtualhost>
    ServerName www.fusioncube.net
    ProxyPass / http://www.fusioncube.net:8080/
</virtualhost>

Configure JBoss to accept requests for multiple domains

What you need to do is create a seperate Host configuration for the edach domain in the server definition file which is located at \jboss\server\default\deploy\jbossweb-tomcat55.sar\server.xml.

Open that file and you’ll see a Host configuration already for localhost. This is the default host meaning that all traffic directed via your web server port (8080) will be directed to your root application. This will be your default domain, meaning the one for which you don’t define a Host.

Now let’s create a new Host designation that will direct requests for two new domain names.

<Host name="domain2 {this can be whatever you want}" autoDeploy="false" deployOnStartup="false" deployXML="false">
    <Alias>www.second-domain-name.com</Alias>

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

    <DefaultContext cookies="true" crossContext="true" override="true"/>
</Host>

<Host name="domain3 {this can be whatever you want}" autoDeploy="false" deployOnStartup="false" deployXML="false">
    <Alias>www.third-domain-name.com</Alias>

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

    <DefaultContext cookies="true" crossContext="true" override="true"/>
</Host>

Define Virtual Hosts for Applications

The last step is to modify the jboss-web.xml file for each application. We’ve set up a brand new Host designation, so now each application can be set up as another root application, except now it sits in its own Host space rather than in the one set up for localhost.

So open up the jboss-web.xml file of the application that will be running for second-domain-name.com. Change the context-root definition to root (/) and then match it up with one of the Host entries you made in the server.xml file.

<jboss-web>
    <context-root>/</context-root>
    <virtual-host>domain2</virtual-host>
</jboss-web>

Similarly for another application that will be served for third-domain-name.com

<jboss-web>
    <context-root>/</context-root>
    <virtual-host>domain3</virtual-host>
</jboss-web>

All you need to do is start/restart your Jboss instance and request for both domain names will now be redirected to the appropriate application. Just be sure that you have made the requisite changes to your DNS records and they have propagated.

A recent discussion with a colleague in San Diego led me to realize that, while I have a lot of seperate snippets of how to setup CF/JBoss, I never published a nice comprehensive, step-by-step post to show how to do it from start to finish.

This post is going to cover how to set up your server to run the JBoss Application Server - parsing ColdFusion code in its web apps. Future posts will cover how to set up JBoss AS/Apache/ColdFusion, and JBoss AS/JBoss WS/ColdFusion.

Step 1: ColdFusion Installer

The first thing you need to do is download and/or run the ColdFusion installation package. During the installation wizard, ensure that you choose to install the J2EE/WAR installation type. When the installer is done, go to the installation directory in which you will see a cfusion.war file.

A WAR file (Web Application aRchive) is simply a ZIP archive, which means you can use whichever program you have for unzipping files. Simply unzip the archive into any location you choose. When done, you will have three directories:

  • META-INF
  • WEB-INF
  • CFIDE

The only two you will be interested in are the WEB-INF and CFIDE directories. You can safely delete the META-INF directory.

Step 2: Install JBoss

Now you can download and install the version of JBoss that you want to run your applications. Installation is as easy as unzipping the downloaded ZIP file to the directory from which you want to run JBoss. When done, you’ll have the following directory structure:
JBoss directory structure

Step 3: Creating Your Application Structure

Notice the SAR and WAR directories under the deploy directory. You need to create one for your new web application. For example, if your application is the website for www.widgets.com, simply create a widgets.war directory.
Create widgets.war directory

Remember the WEB-INF and CFIDE directories you unpacked previously, well now we need them. Copy them from their current location to your new widgets.war web application directory. Amazingly, you are almost done! These two directories are all that is needed to get a JBoss web app to parse ColdFusion files.
JBoss app enabled

Step 4: Telling JBoss You’re Alive

Now, here’s where you need to determine how JBoss is going to serve your Widgets application. This is done by creating a jboss-web.xml file inside the widgets.war\WEB-INF directory.
Jboss-web.xml file

If the Widgets application is the only application you want to server from JBoss, or it is going to be your root application - in both cases, what you want served when someone hits www.widgets.com - you specify this application as the root application. This is what the jboss-web.xml file would look like.
Jboss web root

However, if you want this application to be a subdirectory off of your root, you would specify that subdirectory name in the jboss-web.xml file.
Jboss web subdir

Step 5: Serving Your Application

The last thing you might need to do - if JBoss is functioning as your main web server - is change the port on which JBoss is listening. For this, you need to look inside the deploy\jbossweb-tomcat50.sar\server.xml file.
Jboss tomcat file

The very first setting in this file is the port on which Tomcat is listening for HTTP requests. The default value is 8080, but if JBoss is your default web and application server, you will need to change the port attribute value to 80.
tomcat_server_file.jpg

Conclusion

This is the most basic configuration for JBoss / ColdFusion. After completing these steps, you can start your JBoss instance and hit your designated URL and ColdFusion files will light up.

For more advanced configurations of JBoss, here are some links to other relevant posts.
Running multiple ColdFusion instances
Securing your JBoss web applications
Hosting multiple domains in JBoss
Flexible ColdFusion deployment - serving from anywhere

Java Native Types (Threads) via ColdFusion

I’d published a quick app called Memory Explorer I threw together using Rob Gonda’s ajaxCFC framework a while back. However, one thing that’s been bugging me ever since I made it was that I was using JSP pages to create certain Java objects and then putting them in a scope that ColdFusion could access - specifically the Request scope.

I always knew there had to be a way to create not only a Thread object, but also an array of Threads, however I didn’t make the time to investigate it. Then, by chance, I stumbled across some code I did last year regarding Bytes and Byte arrays and realized that I could use the same principles (after a few blind stabs in the dark) to create what I needed.

I also, then, re-found an article on Chrisian Cantrell’s site regarding creating Byte arrays in ColdFusion which I remembered that I referenced when I did my original code. Using my code and his examples as inspiration, I finally was able to access all of the threads currently running on my JVM and output them nicely to the screen. Here’s what you need to do.

First, create a Thread object which captures the current thread of your JVM
thisThread = createobject(”java”, “java.lang.Thread”);

Then, create a native Java Thread type by using the getClass() method
threadClass = createobject(”java”, “java.lang.Thread”).init().getClass();

Now, you need an Array to hold all of the threads because the ThreadGroup.enumerate() method requires a native Thread array as an argument.
threadList = createobject(”java”, “java.lang.reflect.Array”).newInstance(threadClass,thisThread.activeCount());

Next, you populate the Thread array with each item in the ThreadGroup.
thisThread.currentThread().getThreadGroup().enumerate(threadList);

Now you have your array of Threads which you can access in ColdFusion as a simple one-dimenstional array.
<cfdump var=“#threadList[1]#”>

Connecting ColdFusion to SQL Server Express

I’ve had SQL Server 2005 Express Edition installed for a while just to play around with, but I recently decided to try to develop a ColdFusion application that uses it as the backend - for fun. It turned out not to be fun, but with a little searching and tinkering with some settings, I was able to get ColdFusion 7 to successfully connect to it.

These instructions assume that you have the Microsoft SQL Server Management Studio Express installed to manage these tasks.

1. Open the SQL Server Studio

2. Click on the Registered Servers button in the toolbar

RegisteredServers-709855-png.jpg

3. Open the Configuration Manager
ConfigManager-764825-png.jpg

4. If needed, enable the TCP/IP protocol under SQL Server Configuration Manager > SQL Server 2005 Network Configurations > Protocols for SQLEXPRESS
EnableTCPIP-714206-png.jpg

5. Now double-click the TCP/IP protocol to view the properties. Click on the IP Addresses tab and make sure that the TCP Port is set to 1433 for every IP type.
TCPIPProperties-704436-png.jpg

6. Open the Properties page for your server instance
ServerProperties-739292-png.jpg

7. Go to the Security item and make sure that you have Mixed Mode enabled. After making sure all of the these settings are in place, you should now restart your server.
MixedMode-700059-png.jpg

8. Once the server restarts, create a new login to be used by ColdFusion, give it a SQL Server Authentication password, and set the default database to the one you’re setting up.
ColdFusionUser-735879-png.jpg

9. Now it’s time to set up the ColdFusion datasource. Download the Microsoft SQL Server 2005 JDBC Driver and place the resultant sqljdbc.jar file in the WEB-INF\cfusion\lib directory, or wherever your cfusion\lib directory is located.

10. Log in to your ColdFusion Administrator and create a new datasource with the same name as the database you want to connect to. Make the datasource type ‘other’.

11. Fill in the fields with the following properties
JDBC URL: jdbc:sqlserver://{server name}\sqlexpress:1433
Driver Class: com.microsoft.sqlserver.jdbc.SQLServerDriver
Driver Name: SQL Server 2005 JDBC

Then enter in the username and password you created in step 8 into the appropriate fields. This should get you a successful ColdFusion datasource using SQL Server Express.

Reference Articles
Login failed … not associated with a trusted SQL server connection
SQL Server Express 2005, Finally Installed