RSS Entries RSS
RSS Subscribe by Email

Hosting Ruby on Rails on Shared Hosting at Fastdomain

I’ve been playing around with Ruby on Rails lately. I’m using Instant Rails as a development server locally. However, I wanted to try to publish my first Rails app to the world. I have a shared hosting account at FastDomain.com, but was having a lot of trouble getting it to work. The only error message I was given was “Application Error - Rails application failed to start properly” and I couldn’t find any informative logs. I believe that Fast Domain is run by the same people who run the more well-known BlueHost.com, so these instructions should work for that host too.

After awhile, I figured out that my problem was due to the fact that the permissions were not set properly when I FTP’d the app over. So, I deleted the app and ran “rails appname” to generate the basic rails structure. Then I copied over my app, config, and vendor/plugins directories and the relevant portions of the public directory. After that I was up and running. Make sure not to copy the entire public directory, but only the files you’ve created or edited so that you do not change the permissions of the dispatch scripts. You could also copy everything and run “chmod 755″ afterwards to reset the permissions. If you’re getting a similar error and the steps I described did not help then I recommend checking out this page at Hoopla!

At this point I was up and running, but my app was sloooowwww. The solution I found was to modify the .htaccess file to ensure that fcgi was being used instead of cgi. Makes sense since the f in fcgi stands for fast. So, go to the public directory of your app and change “RewriteRule ^(.*)$ dispatch.cgi [QSA,L]” to “RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]“. At this point, when I visited the site, I was shown the script source instead of having it execute. Turns out that FastDomain uses a different fcgi handler so change the first line of the script (”AddHandler fastcgi-script .fcgi”) to “AddHandler fcgid-script .fcgi” and your app will be blazing fast.

Comments

HTML Parsing Showdown - New Contender Takes Title

One of my first posts was a comparison of HTML parsers. Today I found a particularly challenging document to parse. None of the parsers I had compared earlier were able to handle the malformed HTML in this table where the td elements were prematurely ended. The behavior of Neko and HtmlCleaner made the most sense (while still failing to clean the document) while the output from TagSoup and jTidy was a bit more strange.

However, I noticed that FireBug parsed the document correctly. So I did a bit of research into how I’d be able to use Firefox’s HTML parsing and found a project called Mozilla Parser that had been put together to do just that. Its setup is not quite as nice as the others, but is well documented. Follow the quick start to begin with. Then when you get to the portion where you write actual Java code you may want to follow the example below as it appears the API has been updated since the documentation was posted.

final String BASE_PATH = "C:\\Documents and Settings\\bjm733\\My Documents\\workspace\\MozillaHtmlParser\\";

try {
	File parserLibraryFile = new File(BASE_PATH + "native" + File.separator + "bin" + File.separator + "MozillaParser" + EnviromentController.getSharedLibraryExtension());
	String parseLibrary = parserLibraryFile.getAbsolutePath();
	MozillaParser.init(parseLibrary, BASE_PATH + "mozilla.dist.bin."+EnviromentController.getOperatingSystemName());
	MozillaParser parser = new MozillaParser();
	document = parser.parse("<html><body>hello world</body></html>");
} catch(Exception e) {
	e.printStackTrace();
}

Comments

Wuala Invites Available

Wuala is a p2p backup and remote storage service.  It gives you 1GB of backup space for free and more when you share disk space with others.  If you have a large amount of data or multimedia to backup then this is a much cheaper alternative to services such as Mozy.  All your data is encrypted and replicated multiple times.  There is a very interesting Google tech talk on the subject which shares some insights into the workings of Wuala.  I found the portion dealing with erasure codes to be particularly interesting.  Contact me if you’d like an invite to Wuala.

Also, you may have noticed the pace of blogging my has slowed.  I’ve been extremely busy recently and expect this to continue for the next month or two.  Nonetheless, I am going to make time to post a series of Struts 2 tutorials based off a presentation I gave a few months ago.

Comments (2)

Minimum Libraries Required for Hibernate

This should be in the Hibernate documentation, but I don’t believe it is.  Instead you have to download the binary distribution and open the readme in the lib directory.  Since I frequently find myself downloading the entire archive just to view the readme, I am reposting the relevant sections here.

ehcache-1.2.3.jar (1.2.3)
- EHCache cache
- runtime, optional (required if no other cache provider is set)

jta.jar (unknown)
- Standard JTA API
- runtime, required for standalone operation (outside application server)

xml-apis.jar (unknown)
- Standard JAXP API
- runtime, some SAX parser is required

commons-logging-1.0.4.jar (1.0.4)
- Commons Logging
- runtime, required

asm-attrs.jar (unknown)
- ASM bytecode library
- runtime, required if using ‘cglib’ bytecode provider

dom4j-1.6.1.jar (1.6.1)
- XML configuration & mapping parser
- runtime, required

antlr-2.7.6.jar (2.7.6)
- ANother Tool for Language Recognition
- runtime, required

cglib-2.1.3.jar (2.1.3)
- CGLIB bytecode generator
- runtime, required if using ‘cglib’ bytecode provider

asm.jar (unknown)
- ASM bytecode library
- runtime, required if using ‘cglib’ bytecode provider

commons-collections-2.1.1.jar (2.1.1)
- Commons Collections
- runtime, required

Comments

Change the NetBeans Default JDK

A client sent me some code today to update. He was using the NetBeans, so I downloaded the IDE and fired it up to open the project he’d sent me. Unfortunately, the project wouldn’t compile because he’d written the code in Java 6 while NetBeans was using Java 5. I couldn’t find a NetBeans menu to update the setting, but rather found that the fix is to add the following in NetBean’s etc/netbeans.conf file:

# Default location of JDK, can be overridden by using –jdkhome <dir>:
netbeans_jdkhome=”C:\Program Files\Java\jdk1.6.0_05″

Comments

Intro to URL Rewriting with Apache’s .htaccess

I have created an .htaccess file to do URL rewriting for every site I’ve ever created. If you’re not familiar with URL rewriting, it is used to modify a URL or redirect the user before the requested resource is fetched. One of its major uses is to make URLs human readable. That means your users can visit a pretty URL like http://www.tabworldonline.com/guitar/A/ and have it interpreted by the server as http://www.tabworldonline.com/artists.php?instrument=guitar&letter=A.

Most of the time, this file can be relatively simple. I would always recommend using one for URL canonicalization, which is a fancy term for making sure you have one unique URL for each page. For example, lumidant.com redirects to www.lumidant.com. This is beneficial for SEO because you want to ensure that search engines don’t split your ranking points between pages that are actually one and the same.

The code below is the .htaccess file from this site. The declarations in the file are regular expressions, which you might need to get a quick refresher on if you’re not familiar with. A few other things to be aware of include the fact that [NC] stands for no case and means that the text is not case-sensitive, [R=301] tells the server to do a 301 redirect, and [L] tells the server it can quit there and and not bother processing the rest of the file.

<IfModule mod_rewrite.c>

  RewriteEngine on

  # rewrite all lumidant.com requests to the lumidant subdirectory
  RewriteCond %{HTTP_HOST} ^(www\.)?lumidant\.com$
  # this is needed to stop infinite looping
  RewriteCond %{REQUEST_URI} !^/lumidant/.*$
  # don't redirect these directories to the lumidant subdirectory
  RewriteCond %{REQUEST_URI} !^/pinknews/.*$
  RewriteRule ^(.*)$ /lumidant/$1

  # if you're asking for a directory and there is no trailing slash then add one
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteCond %{REQUEST_URI} !^.*/$
  RewriteRule ^/lumidant/(.*)$ http://www\.lumidant\.com%{REQUEST_URI}/ [R=301,L]

  # add a www if there’s not one
  RewriteCond %{HTTP_HOST} ^lumidant\.com$ [NC]
  RewriteCond %{REQUEST_URI} !^/blog.*$
  RewriteRule ^lumidant/(.*)$ http://www\.lumidant\.com/$1 [R=301,L]

</IfModule>

This blog is currently hosted with BlueHost. For accounts with multiple domains, BlueHost places the add-on domains in subdirectories of the main domain. This can be confusing to maintain, so I moved all of the lumidant code to a subdirectory as well and then updated the .htaccess file to make this organization transparent to the end user.

The last few lines add a www to all non-www pages. While I could have placed this at the beginning of the file, the file would be executed again after the redirect causing possibly another redirect to be executed if a trailing slash needed to be added. Keep in mind while organizing the file that you’d like to minimize the number of redirects for many reasons including response times, reducing server load, and optimizing for search engines.

URL rewriting can be tricky at first, especially if you’re not familiar with regular expressions. If you’re working with redirections, then it may help to check the HTTP headers of your request to see what intermediate redirects are occurring.

Finally, if you’re not using Apache there are other alternatives to .htaccess. For example, I have used the UrlRewriteFilter in the past for Java web apps.

Comments

Suppressing Compile Warnings with Java Annotations

If you’ve used Java 1.5 Generics much then you’re probably familiar with the following compile warning: “Type safety: The expression of type List needs unchecked conversion to conform to List<String>” or similar. It turns out there’s a rather simple solution with annotations to ignore this problem:

@SuppressWarnings(”unchecked”)

A couple other possible uses of the annotation that might be of interest are:

@SuppressWarnings(”deprecation”)
@SuppressWarnings(”serial”)

These are compiler specific, so you may want to check out the full Eclipse list, which is a bit lengthier than Sun’s 7 options (all, deprecation, unchecked, fallthrough, path, serial, and finally).

Also, multiple statements can be combined into one as follows:

@SuppressWarnings({”unchecked”, “deprecation”})

Comments

Apache CXF Tutorial - WS-Security with Spring

This tutorial will cover adding an authentication component to your web service though WS-Security. If you need an overview of how to setup CXF then you may find our previous tutorial helpful. Another helpful resource is CXF’s own WS-Security tutorial. However, it does not include information on how to setup the client through Spring.

To begin with, make sure you have at least the following .jars in addition to the required base CXF .jars:

spring-beans-2.0.6.jar
spring-context-2.0.6.jar
spring-core-2.0.6.jar
spring-web-2.0.6.jar
wss4j-1.5.1.jar
xmlsec-1.3.0.jar

Now we will add a security interceptor to the server’s Spring configuration file, which we named cxf.xml in the last tutorial in order to match the CXF documentation.

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd
                          http://cxf.apache.org/jaxws
                          http://cxf.apache.org/schemas/jaxws.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

  <jaxws:endpoint id="auth"
                  implementor="com.company.auth.service.AuthServiceImpl"
                  address="/corporateAuth">

    <jaxws:inInterceptors>
      <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
      <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <constructor-arg>
          <map>
            <entry key="action" value="UsernameToken" />
            <entry key="passwordType" value="PasswordText" />
            <entry key="passwordCallbackClass" value="com.company.auth.service.ServerPasswordCallback" />
          </map>
        </constructor-arg>
      </bean>
    </jaxws:inInterceptors>

  </jaxws:endpoint>

</beans>

You can change the action and passwordType to do more advanced authentication. In this example, we will simply require all authenticating clients to know a single password specified by the server. If you’d like each client to have it’s own password you can specify that in the callback, which is the next thing we must implement:

package com.company.auth.service;

import java.io.IOException;
import java.util.ResourceBundle;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ServerPasswordCallback implements CallbackHandler {

	private static final String BUNDLE_LOCATION = "com.company.auth.authServer";
	private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";

	private static String password;
	static {
		final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
		password = bundle.getString(PASSWORD_PROPERTY_NAME);
	}

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

        // Set the password on the callback. This will be compared to the
        //     password which was sent from the client.
        // We can call pc.getIdentifer() right here to check the username
        //     if we want each client to have it’s own password.
        pc.setPassword(password);
    }

}

The server is now setup to require a password. The password we are requiring is one that we specified in a properties file and then read in through a ResourceBundle. You may find it easier to simply hard code the password on the initial run and then replace it with your own means of authentication once the service is up and running.

If you are running on WebLogic 9, as I was, then you will get an error “java.lang.UnsupportedOperationException: This class does not support SAAJ 1.1“. In order to correct that, make sure your version of the SAAJ classes are being used by adding the following to your weblogic.xml descriptor file:

<container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>

You WebLogic folks must also then set two properties in your WebLogic JDK:

-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
-Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl

We now have to setup the client to supply a password. Firstly, we will create another Spring file at com/company/auth/service/cxfClient.xml to setup the application context for the client:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                      http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

  <bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
    <property name="serviceClass" value="com.company.auth.service.AuthService"/>
    <property name="address" value="http://localhost:7001/authManager/services/corporateAuth"/>
    <property name="inInterceptors">
      <list>
        <ref bean="logIn" />
      </list>
    </property>
    <property name="outInterceptors">
      <list>
        <ref bean="logOut" />
        <ref bean="saajOut" />
        <ref bean="wss4jOut" />
      </list>
    </property>
  </bean>

  <bean id="client" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" factory-bean="proxyFactory" factory-method="create" />

  <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
  <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
  <bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
  <bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="UsernameToken" />
        <entry key="user" value="ws-client" />
        <entry key="passwordType" value="PasswordText" />
        <entry key="passwordCallbackClass" value="com.company.auth.service.ClientPasswordCallback" />
      </map>
    </constructor-arg>
  </bean>    

</beans>

We then need to set the password for our message:

package com.company.auth.service;

import java.io.IOException;
import java.util.ResourceBundle;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler {

	private static final String BUNDLE_LOCATION = "com.company.auth.authClient";
	private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";	

	private static String password;
	static {
		final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
		password = bundle.getString(PASSWORD_PROPERTY_NAME);
	}	

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

        // set the password for our message.
        pc.setPassword(password);
    }

}

Finally, we create the service factory, which is extremely easy since all the work was done in the Spring file:

package com.company.auth.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class AuthServiceFactory {

    private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
                “com/company/auth/service/cxfClient.xml”
            });

    public AuthServiceFactory() {
    }

    public AuthService getService() {
        return (AuthService) context.getBean(”client”);
    }
}

Congratulations. Your web service now utilizes a basic implementation of WS-Security. Hopefully, that will be enough background to get you on your way.

Comments (12)

Adding Links for Navigation to the WordPress Pages List

The category titled “Pages” on the right-hand side of this blog is an area where WordPress will allow a user to create wiki pages. However, I wanted to include some navigational links in that area as well, which isn’t immediately available through the WordPress admin screens.

The solution I found was to create a new blogroll category and use it for navigational links. First off, I modified the call to wp_list_pages by adding the argument “title_li=0″, which tells WordPress not to wrap it in <ul> tags, but to instead only output the <li> tags. Then I wrapped the call with my own <ul> tags. Finally, I called wp_list_bookmarks in order to display the category I had created, which had an id of 34. I again used the “title_li=0″ parameter and also had to add “categorize=0″, so that this parameter would not be ignored:

	<li id="pages">
		<h2><?php _e('Pages'); ?></h2>
		<ul>
			<?php wp_list_bookmarks('categorize=0&title_li=0&category=34'); ?>
			<?php wp_list_pages('title_li=0'); ?>
		</ul>
	</li>

Comments

hCard Microformat Example

What exactly is an hCard? It’s a format which specifies that some information on a web page is an online business card. The address for Lumidant in the page footer is an hCard. This means when someone with the Operator Firefox extension visits this page they will have the opportunity to do a one-click import of Lumidant’s address and URL into their contact book. And that can’t hurt business. Come Firefox 3, this functionality will be available without extensions. Creating an hCard was pretty simple. All I had to do was add specific class names to my HTML elements:

        <div id="address" class="vcard">
          <a class="fn org url" href="http://www.lumidant.com" title="Lumidant | Cleveland Web Design and Development">
            Lumidant LLC
          </a>
          ·
          <span class="adr">
            <span class="street-address">1220 West Sixth Street</span> |
            <span class="extended-address">Suite 506</span> |
            <span class="locality">Cleveland</span>,
            <span class="region">OH</span>
            <span class="postal-code">44113</span>
          </span>
          · <a href="blog/">Blog</a>
        </div>

Comments