Case Insensitive Usernames using Spring Security Core Plugin for Grails

Given the years I’ve worked with Spring Security, it’s a bit embarrassing how often I forget that, by default, if you’re using the default database-backed implementation, the login is case sensitive. The best place to modify this behavior by overriding it in the UserDetailsService implementation you’ve selected.

Most of my most recent projects have been in Grails1. This is a framework I’ve found to be very flexible and fast for development. And usually the first plugin I install is the Spring Security Core.

Making your login case insensitive (which has always been my choice, since it eliminates irritating user experience issues) turns out to be quite simple. The plugin provides GormUserDetailsService as the default implementation. Override this class and update your resource.groovy to use it instead of the default.

The first example shows how to override if you want to go for simplicity in your code because it’s application specific. Rather than dynamically loading the user domain class, we’ll just use it directly, since we know what it is for this application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.stevideter
 
import org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
class CaseInsensitiveUserDetailsService extends GormUserDetailsService {
 
	/**
	 * make username case insensitive. Since we're using in a specific app,
	 * let's directly use the known class and property name
	 */
	UserDetails loadUserByUsername(String username, boolean loadRoles) 
			throws UsernameNotFoundException {
		// in this example, I used Person as my domain class
		Person.withTransaction { status ->
			def user = Person.findByUsernameIlike(username)
			if (!user) {
				log.warn "User not found: $username"
				throw new UsernameNotFoundException('User not found', username)
			}
 
			Collection<GrantedAuthority> authorities = 
				loadAuthorities(user, username, loadRoles)
			createUserDetails user, authorities
		}
	}
}

Then register this bean in resources.groovy, and you’re ready to log in without worrying about case:

1
2
3
beans = {
	userDetailsService(com.stevideter.CaseInsensitiveUserDetailsService)
}

But what if you want to be more generic in your approach? That’s still possible, we just need to remember to inject grailsApplication into our Service class so we can dynamically load the domain class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.stevideter
 
import org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
 
class DynamicCaseInsensitiveUserDetailsService extends GormUserDetailsService {
 
	def grailsApplication
 
	UserDetails loadUserByUsername(String username, boolean loadRoles)
			throws UsernameNotFoundException {
		def conf = SpringSecurityUtils.securityConfig
		String userClassName = conf.userLookup.userDomainClassName
		def dc = grailsApplication.getDomainClass(userClassName)
		if (!dc) {
			throw new RuntimeException("The specified user domain class '$userClassName' is not a domain class")
		}
 
		Class<?> User = dc.clazz
 
		User.withTransaction { status ->
			// this time we'll use where plus a DetachedCriteria closure 
			// with =~ for case insensitivity
			def user = User.where{
				(conf.userLookup.usernamePropertyName) =~ username
			}.find()
			if (!user) {
				log.warn "User not found: $username"
				throw new UsernameNotFoundException('User not found', username)
			}
			log.debug "found user"
 
			Collection<GrantedAuthority> authorities = 
				loadAuthorities(user, username, loadRoles)
			createUserDetails user, authorities
		}
	}
}
1
2
3
4
5
beans = {
	userDetailsService(com.stevideter.DynamicCaseInsensitiveUserDetailsService) {
		grailsApplication = ref('grailsApplication')
	}
}

In the first example, it’s possible to easily use a dynamic finder to create our query, but in the second, I chose to use the where method with a Detached Criteria to find the user.

The UserDetailsService is an important part of Spring Security, as it’s also where you’ll want to make any changes to the UserDetails returned from the authentication process.

[1] Just Grails. See the link in Burt Beckwith’s comment for why.

The Passionate Programmer

The Passionate Programmer A few years ago, right about the time I learned my job was to be outsourced, I remember seeing a book in the bookstore titled My Job Went to India. I assumed it was a parody of sorts and decided to resist the urge to pick it up.

It wasn’t until I read the introduction to The Passionate Programmer by Chad Fowler, that I realized it was the second edition of that same book, which had been subtitled “52 Ways to Save Your Job.” The title change is a good one, as it does a much better job of crystallizing the goal of this book.

The focus of The Passionate Programmer is how to have an exceptional career as a developer. It is written as several short essays on specific tips for creating a career in programming you can be passionate about, each followed by one or more specific suggestions for activities to follow through on what you’ve just read. In essence, this is What Color Is Your Parachute? for people who already know they want to be programmers.

While the driving force may be passion, the topics are very pragmatic. Fowler suggests you choose your market, invest in your product, execute on your plans, and market yourself. This follows from the major thesis, that you must treat your career as a product in and of itself. The passion comes from the desire to create a great product, and do what is necessary to make that product, ultimately yourself, successful.

An important point that’s treated as a side note – you have to want to be a great programmer. If you find that’s not what you want, maybe you should find a career you can be passionate about.

Fowler provides a road map for how to create a career you love on a daily basis while moving towards a future you are excited about. The topics range from how to find enjoyment in the drudge tasks you may hate, how to keep from falling behind the technology curve, how to decide when to take career risks, and how to become truly remarkable (not just good).

Most of the “Act On It” tasks are highly relevant and useful. Now that I have read the entire book, I plan to review the chapters that feel the most relevant and focus on one or two of the tasks a week.

While much of the advice provided the The Passionate Programmer is not new, I think this is a great resource for anybody who wants to have a career as a software developer that excites and inspires. Software is a great industry, full of brilliant people and complex problems to solve. That’s why I got into it. This book provides concrete ways I can keep that passion alive.

&lt;a href=”http://www.amazon.com/gp/product/0976694018?ie=UTF8&tag=movithecurv-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0976694018″&gt;My Job Went to India: 52 Ways to Save Your Job (Pragmatic Programmers)&lt;/a&gt;&lt;img src=”http://www.assoc-amazon.com/e/ir?t=movithecurv-20&l=as2&o=1&a=0976694018″ width=”1″ height=”1″ border=”0″ alt=”" style=”border:none !important; margin:0px !important;” /&gt;

Of ExceptionResolvers and XMLBeans

We’re using XMLBeans with Spring Web Services, and the set-up was quite easy. But the one issue I found frustrating was handling the SoapFault. The requirements in this case required including a SoapFaultDetail that contained a complex type. And while the XmlBeansMarshaller transparently handles transforming the incoming and outgoing SOAP requests, it didn’t magically include the type defined as the fault in the WSDL within the SoapFault message.

Digging through the tutorial and some online forum postings, I finally found a solution. The AbstractSoapFaultDefinitionExceptionResolver provides a protected method void customizeFault(Object endpoint, Exception ex, SoapFault fault) that subclasses can override to modify the SoapFault before it is returned. Since this method includes the exception as a parameter, I chose to create an exception that is thrown by my endpoints that includes my desired XmlBean, already populated, so I can just use SoapFault.getResult() to marshall the information into the details.

For simplicity’s sake, I chose to override the existing SoapFaultMappingExceptionResolver.

Below, ServiceFaultDocument is an XmlObject generated by XMLBeans from my schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  xmlns:s1="http://stevideter.com/webservice">
    <xs:element name="ServiceFault" type="s1:ServiceFault"/>
    <xs:complexType name="ServiceFault">
        <xs:sequence>
            <xs:element name="errorCode" type="xs:string" minOccurs="0" maxOccurs="1"/>
	    <xs:element name="errorDescription" type="xs:string" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

For my Exception class:

package com.stevideter.webservice;
 
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
 
import com.stevideter.webservice.ServiceFaultDocument;
/**
 * An exception that carries a ServiceFault document for inclusion in 
 * the SoapFault
 * @author stevi.deter
 *
 */
@SoapFault(faultCode = FaultCode.SERVER,faultStringOrReason="SERVICE-ERR",locale="en")
public class ServiceFaultException extends Exception {
 
	private static final long serialVersionUID = 1L;
	private ServiceFaultDocument faultMessage;
 
	public ServiceFaultException() {
		super("ServiceFaultException");
	}
 
	public ServiceFaultException(String s) {
		super(s);
	}
 
	public ServiceFaultException(String s, Throwable ex) {
		super(s, ex);
	}
 
	public ServiceFaultException(String s, Throwable ex, ServiceFaultDocument msg) {
		super(s,ex);
		setFaultMessage(msg);
 
	}
 
	public void setFaultMessage(ServiceFaultDocument msg) {
		faultMessage = msg;
	}
 
	public ServiceFaultDocument getFaultMessage() {
		return faultMessage;
	}
 
}

And finally my ExceptionResolver. Note that logger is ultimately inherited from AbstractEndpointExceptionResolver, which is why you don’t see it declared in the code displayed.

package com.stevideter.webservice.soap.server.endpoint;
 
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
 
import org.springframework.ws.soap.SoapFault;
import org.springframework.ws.soap.SoapFaultDetail;
import org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver;
import org.springframework.xml.transform.StringSource;
 
import com.stevideter.webservice.ServiceFaultException;
import com.stevideter.webservice.ServiceFaultDocument;
 
public class DetailSoapFaultDefinitionExceptionResolver extends
		SoapFaultMappingExceptionResolver {
 
	@Override
	protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) {
		ServiceFaultException msg = null;
		if (ex instanceof ServiceFaultException) {
			msg = (ServiceFaultException) ex;
		} else {
			msg = createFaultMessage(ex);
		}
		addServiceFaultDetail(msg, fault);
	}
 
	private void addServiceFaultDetail(ServiceFaultException msg, SoapFault fault)
			throws TransformerFactoryConfigurationError {
		Transformer trn;
		try {
			trn = TransformerFactory.newInstance().newTransformer();
			SoapFaultDetail faultDetail = fault.addFaultDetail();
			Result result = faultDetail.getResult();
			ServiceFaultDocument doc = msg.getFaultMessage();
			if (doc == null) {
				logger.error("ServiceFaultException thrown with no serviceFaultDocument!",msg);
			} else {
				trn.transform(new StringSource(doc.toString()), result);
			}
		} catch (TransformerException e) {
			logger.error("problem with XML transform: ", e);
		}
	}
 
	private ServiceFaultException createFaultMessage(Exception e) {
		ServiceFaultDocument faultDocument = ServiceFaultDocument.Factory.newInstance();
		ServiceFault fault = faultDocument.addNewServiceFault();
		fault.setErrorCode("SERVICE-ERR");
		fault.setErrorDescription(e.getMessage());
		ServiceFaultException faultMsg = new ServiceFaultException(e.getMessage(),e,faultDocument);
		return faultMsg;
	}
}

The final step is injecting my ExceptionResolver in my webservice’s servlet.xml; just showing the single bean definition here:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- rest of web service bean def's elided -->
 
    <bean id="exceptionResolver"
	        class="com.stevideter.webservice.soap.server.endpoint.DetailSoapFaultDefinitionExceptionResolver">
        <property name="defaultFault" value="SERVER"/>
        <property name="exceptionMappings">
            <value>
	    com.stevideter.webservice.ServiceFaultException=SERVER,FaultMsg
            </value>
	</property>
    </bean>
</beans>

Now whether my Endpoints throw an Exception, the ExceptionResolver transforms it into the SoapFaultDetail, and the calling system get the results they desire:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Server</faultcode>
         <faultstring xml:lang="en">FaultMsg</faultstring>
         <detail>
            <ServiceFault xmlns="http://stevideter.com/webservice">
               <errorCode xmlns="">SERVICE-ERR</errorCode>
               <errorDescription xmlns="">you can't do that!</errorDescription>
            </ServiceFault>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

One issue I discovered in developing this was that we were using Saxon 8.8, a version which apparently has a bug that throws an exception on the empty namespaces in the Service Fault elements during the transform. According to the information I found, upgrading to Saxon 8.9 fixes that; I went ahead and upgraded to Saxon 9.1.0.5 (current version as I write this) and the problem went away. Be sure to include saxon9.jar and saxon9-dom.jar if you go this route!

How have you used ExceptionResolvers in Web Services?

SaveOrUpdate versus Merge in Hibernate

We all have those problems that we encounter just infrequently enough that when we see them again, we know we’ve solved this, but can’t remember how.

The NonUniqueObjectException thrown when using Session.saveOrUpdate() in Hibernate is one of mine. I’ll be adding new functionality to a complex application. All my unit tests work fine. Then in testing the UI, trying to save an object, I start getting an exception with the message “a different object with the same identifier value was already associated with the session.” Here’s some example code from Java Persistence with Hibernate.

Session session = sessionFactory1.openSession();
Transaction tx = session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(1234));
tx.commit();
session.close(); // end of first session, item is detached
 
item.getId(); // The database identity is "1234"
item.setDescription("my new description");
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
Item item2 = (Item) session2.get(Item.class, new Long(1234));
session2.update(item); // Throws NonUniqueObjectException
tx2.commit();
session2.close();

To understand the cause of this exception, it’s important to understand detached objects and what happens when you call saveOrUpdate() (or just update()) on a detached object.

When we close an individual Hibernate Session, the persistent objects we are working with are detached. This means the data is still in the application’s memory, but Hibernate is no longer responsible for tracking changes to the objects.

If we then modify our detached object and want to update it, we have to reattach the object. During that reattachment process, Hibernate will check to see if there are any other copies of the same object. If it finds any, it has to tell us it doesn’t know what the “real” copy is any more. Perhaps other changes were made to those other copies that we expect to be saved, but Hibernate doesn’t know about them, because it wasn’t managing them at the time.

Rather than save possibly bad data, Hibernate tells us about the problem via the NonUniqueObjectException.

So what are we to do? In Hibernate 3, we have merge() (in Hibernate 2, use saveOrUpdateCopy()). This method will force Hibernate to copy any changes from other detached instances onto the instance you want to save, and thus merges all the changes in memory before the save.

Session session = sessionFactory1.openSession();
Transaction tx = session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(1234));
tx.commit();
session.close(); // end of first session, item is detached
 
item.getId(); // The database identity is "1234"
item.setDescription("my new description");
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
Item item2 = (Item) session2.get(Item.class, new Long(1234));
Item item3 = session2.merge(item); // Success!
tx2.commit();
session2.close();

It’s important to note that merge returns a reference to the newly updated version of the instance. It isn’t reattaching item to the Session. If you test for instance equality (item == item3), you’ll find it returns false in this case. You will probably want to work with item3 from this point forward.

It’s also important to note that the Java Persistence API (JPA) doesn’t have a concept of detached and reattached objects, and uses EntityManager.persist() and EntityManager.merge().

I’ve found in general that when using Hibernate, saveOrUpdate() is usually sufficient for my needs. I usually only need to use merge when I have objects that can have references to objects of the same type. Most recently, the cause of the exception was in the code validating that the reference wasn’t recursive. I was loading the same object into my session as part of the validation, causing the error.

Where have you encountered this problem? Did merge work for you or did you need another solution? Do you prefer to always use merge, or prefer to use it only as needed for specific cases?

Annotation Mapping for Ordered Lists in Hibernate

Here’s another problem that has a simple solution that took me longer than I expected to find.

I am using Hibernate 3.2.5 as my ORM. In one case, I want to map a child collection of items as an ordered List, taking advantage of the database to do my ordering.

I’m using Annotations intead of the hbm.xml format for my mappings in this project. Whenever possible, I’m using javax.persistence mappings in preference too Hibernate’s annoations.

Referring to Java Persistence with Hibernate, the mapping looks quite complicated, using Hibernate’s annotations. With some experimentation, I found a simple solution, using just the javax.persistence mappings. For simplicity, I’ll show the example annotating the Item / Bid class idea we’re used to from the Hibernate Caveat Emptor example.

package com.stevideter.domain;
 
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
 
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
 
import org.apache.commons.collections.CollectionUtils;
 
@Entity
@Table(name = "ITEM")
public class Item implements Serializable {
 
  private static final long serialVersionUID = -7990110946186412551L;
  private Integer id;
  private List bids = new ArrayList();
 
  @Id
  public Integer getId() {
    return id;
  }
 
  public void setId(Integer id) {
    this.id = id;
  }
 
  @OneToMany(mappedBy="item",cascade=CascadeType.ALL)
  @OrderBy("userId,date,amount")
  public List getBids() {
    return bids;
  }
 
  private void setBids(List bids) {
    this.bids = bids;
  }
 
  public void addBid(Bid bid) {
    if (CollectionUtils.isEmpty(bids)) { bids = new ArrayList();}
    bids.add(bid);
    bid.setItem(this);
  }
 
  public void removeBid(Bid bid) {
    if (CollectionUtils.isNotEmpty(bids)) {
      bids.remove(bid);
    }
  }
 
}

And for reference, here’s the mapping in the Bid with the Item as a parent:

package com.stevideter.domain;
 
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
 
@Entity
@Table(name = "BID")
public class Bid implements Serializable {
 
  private static final long serialVersionUID = 8165733510722884274L;
  private Integer id;
  private Item item;
  private Date date;
  private BigDecimal amount;
  private Integer userId;
 
  @Id
  public Integer getId() {
    return id;
  }
 
  public void setId(Integer id) {
    this.id = id;
  }
 
  @ManyToOne( targetEntity = com.stevideter.domain.Item.class )
  @JoinColumn(name = "itemid", nullable = false)
  public Item getItem() {
    return item;
  }
 
  public void setItem(Item item) {
    this.item = item;
  }
 
  public Date getDate() {
    return date;
  }
 
  public void setDate(Date date) {
    this.date = date;
  }
 
  public BigDecimal getAmount() {
    return amount;
  }
 
  public void setAmount(BigDecimal amount) {
    this.amount = amount;
  }
 
  public Integer getUserId() {
    return userId;
  }
 
  public void setUserId(Integer userId) {
    this.userId = userId;
  }
 
}

With this mapping, the bids collection is managed by the Item, so saving the Item automatically saves the bid collection.

This example does follow the JPA standard of configuration by exception, so column names, etc., that are not explicitly called out follow the default standards.

What has been your trickiest Hibernate or javax.persistence mapping problem? How did you solve it?


Edited to make mapping on Bids properly bidirectional.

Finding selected checkbox items in a JSF dataTable

This is one of those problems that I couldn’t find a complete example for when I needed it, so hopefully this will save somebody else the extra time it took me to piece it together.

We frequently need to have data tables in our UI, and allow the user to select a subset of those items for action. In JavaServer Faces, this means having a DataTable, each row having its own checkbox. But when the action is triggered, how to we find which items the user has selected.

The first step is to add a boolean property to your objects that can represent the selection. If you have a lot objects in your domain that will need this property, you may want to consider adding this to an interface or parent bean, otherwise, you can add it directly to your domain object. As a caveat, I don’t like adding properties to my domain objects that are for UI use only, but in this case, I’m keeping this as simple as possible. Sometimes pragmatism wins.

package com.stevideter.domain;
 
public class SelectableItem {
 
  private Integer id;
  private String name;
  private boolean selected;
 
  public Integer getId() {
    return id;
  }
 
  public void setId(Integer id) {
    this.id = id;
  }
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public boolean isSelected() {
    return selected;
  }
 
  public void setSelected(boolean selected) {
    this.selected = selected;
  }
}

In your view, you’ll use the dataTable to display the items, including the checkbox:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
 
<f:view><html><body>
<h:form>
<h:dataTable id="itemsTable" 
    value="#{SelectionBean.selectedItems}" var="item"  >
 
<f:facet name="header">
  <h:outputText value="Items" />
</f:facet> 
<h:column>
  <f:facet name="header">
    <h:outputText value="Select" />
  </f:facet>
  <h:selectBooleanCheckbox value="#{item.selected}" />
</h:column>
<h:column>
  <f:facet name="header">
    <h:outputText value="name" />  
  </f:facet> 
    <h:outputText value="#{item.name}"></h:outputText>
</h:column>
</h:dataTable>
<h:commandButton title="selectItems" 
    value="Select Items"
    actionListener="#{SelectionBean.submitSelections}" />
</h:form>
</body></html></f:view>

Now when you click the command button to trigger the submitSelections event, the boolean values for selected items will be set, and you can iterate through your list to find the selected items and act on them as needed.

package com.stevideter.BackingBean;
 
import java.util.List;
 
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
 
import com.stevideter.domain.SelectableItem;
import com.stevideter.manager.DomainManager;
 
public class SelectionBean {
 
  private DataModel selectableItems;
  private DomainManager manager;
 
  public void populateSelectableItems(ActionEvent event) {
    selectableItems = new ListDataModel();
    selectableItems.add(manager.getSelectableItems());
  }
 
  public void submitSelections(ActionEvent event) {
    List<SelectableItem> items = (List<SelectableItem>)selectableItems.getWrappedData();
    List<SelectableItem> selectedItems = new ArrayList<SelectableItem>();
    for (SelectableItem item : items) {
      if (item.isSelected()) {
        selectedItems.add(item);
      }
    }
    // do what you need to do with selected items
  }
 
  public DataModel getSelectableItems() {
    return selectableItems;
  }
 
  public void setSelectableItems(DataModel selectableItems) {
    this.selectableItems = selectableItems;
  }
}

As you can see, this is a very simple solution. Have you seen any other approaches that work?

First actual case of bug being found

On September 9, 1947, the Harvard University Mark II Aiken Relay Calculator started having problems. The operators opened it up, and discovered a moth between the points of Relay #70, in Panel F. The moth was removed at taped into the log book with the comment “First actual case of bug being found.”

When told of the event, Grace Murray Hopper was reported to have quipped they were “debugging” the machine. There is plenty of evidence the term “bug” for a flaw in electronics had been around for decades before this event, this usage helped bring it into the modern popular terminology.

This is also the first introduction that many of us have to Rear Admiral Hopper, a truly remarkable woman. She wrote the first compiler for an electronic computer, A-0. She championed the idea that computer languages should be more like English instead of machine code. And she helped establish standards for testing systems and components.

The next time I have to debug a program written in a 3GL, I’ll take a moment to thank Grace Hopper for laying the groundwork that made it easier for me. Thank you, Amazing Grace!

How to configure a secure JMS connection using Spring

In a comment to my previous post about configuring JMS via Spring, Vikas Kadam asked about configuring a connection to a secure TIBCO EMS topic or queue. As fate would have it, the next issue I dealt with was adding this to my own application. What worked for me was using Spring’s UserCredentialsConnectionFactoryAdapter as my connection factory for my JmsTemplate. The final configuration looked like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
  <bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location"
      value="file:${catalina.home}/conf/jms.properties" />
  </bean>
 
  <bean id="messageSender"
    class="com.stevideter.spring.jms.MessageSender">
    <property name="jmsTemplate" ref="jmsTemplate" />
  </bean>
 
  <bean id="jmsTemplate"
    class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory"
      ref="userCredentialsConnectionFactory" />
    <property name="defaultDestinationName"
      value="${jms.defaultdestinationname}" />
    <property name="pubSubDomain" value="${jms.istopic}" />
  </bean>
 
  <bean id="userCredentialsConnectionFactory"
    class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    <property name="targetConnectionFactory">
      <ref bean="topicConnectionFactory" />
    </property>
    <property name="username" value="${jms.username}" />
    <property name="password" value="${jms.password}" />
  </bean>
 
  <bean id="topicConnectionFactory"
    class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName"
      value="${jms.connectionfactory}" />
  </bean>
 
  <bean id="jndiTemplate"
    class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
      <props>
        <prop key="java.naming.factory.initial">
          com.tibco.tibjms.naming.TibjmsInitialContextFactory
        </prop>
        <prop key="java.naming.provider.url">
          ${jms.jndicontexturl}
        </prop>
      </props>
    </property>
  </bean>
</beans>

Simplifying Spring’s JMS configuration for JndiTemplate

I’ve spent several days, off and on, wrestling with a chicken-and-egg configuration issue.

I have an application that uses Spring 2.0 and is deployed to Tomcat 5.5. We make heavy use of Tomcat’s JNDI for configuring things like our database connections.

We’re adding JMS functionality to our application; at this point, we merely need to send events to an existing Tibco EMS 4.4 Topic.

Following the various online tutorials, I was able to use Spring to make my JMS code very lightweight. I was pretty happy with things overall, until I encountered the final problem of setting up the configuration.

The Tibco EMS Server provides its own JNDI services, which I need to connect to the correct topic connection factory. I can use Spring’s JndiTemplate to configure this additional JNDI connection, but I kept hitting one problem. In every environment I’m going to deploy to, the value for java.naming.provider.url will be different. Because JndiTemplate is using

for setting the environment, I can’t use a separate JNDI lookup to populate that value out of Tomcat’s JNDI.

I needed to abstract this value out of my war file, into a configuration file that can stay on each server, so I don’t have to change it every time. This is an application that gets deployed fresh each new revision, and the client wasn’t going to be happy to have to extract the war file and then edit a config file, when that’s never been needed in the past. In addition, each server we’re deploying to already has a JNDI configuration for the Tibco EMS server. But, no matter how I tried, I could not find a way to configure the Tomcat JNDI to let me access those values from the Spring configuration file within the application.

The solution I found that finally worked was to use a PropertyPlaceholderConfigurer that pointed to a file in the tomcat conf directory. The final hurdle I had to jump was the correct configuration. If I used property=”location” value=”${catalina.home}/conf/jms.properties”, Spring would attempt to resolve the value from the servlet container by prepending a slash in front of the catalina.home directory. If I attempted to use a relative path, tomcat wouldn’t allow me open and read the file. I finally hit on prefixing the path with “file:” which was the magic to let Spring know I meant an absolute file path.

I am annoyed I have to add a configuration file, but at least it’s one more place where we can set the value and forget about it for future deployments.

In case anybody hits this combination of problems, here’s what finally worked:

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.springframework.org/schema/jee 
       http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
 
           <bean id="propertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>file:${catalina.home}/conf/jms.properties</value>
                    <value>/WEB-INF/jdbc.properties</value>
                </list>
            </property>
        </bean>
 
    <bean id="messageSender"  
             class="com.stevideter.spring.jms.MessageSender">
        <property name="jmsTemplate" ref="jmsTemplate" />
    </bean>
 
    <bean id="jmsTemplate" 
              class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="topicConnectionFactory" />
        <property name="defaultDestinationName">
            <jee:jndi-lookup jndi-name="java:comp/env/jms/eventdestname"/>
        </property>
        <property name="pubSubDomain" value="true" />
    </bean>
 
    <bean id="topicConnectionFactory" 
             class="org.springframework.jndi.JndiObjectFactoryBean">
       <property name="jndiTemplate" ref="jndiTemplate"/>
       <property name="jndiName" value="FTTopicConnectionFactory"/>
    </bean>
 
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
           <property name="environment">
                  <props>
                         <prop key="java.naming.factory.initial">
                            com.tibco.tibjms.naming.TibjmsInitialContextFactory
                         </prop>
                         <prop key="java.naming.provider.url">
                            ${jms.jndicontexturl}
                         </prop>
                  </props>
           </property>
    </bean>
</beans>

Picking the right .NET Framework Version with Specific Reference

This morning I needed to work on a long-standing ASP.NET web application project. I haven’t had to run it locally for quite a while. I updated my source from TFS, cleaned and built the solution, and started the project in debug mode. After logging in, I went to a page, and was suddenly staring at an unexpected and confusing exception:

The base class includes the field 'ScriptManager1', 
but its type (System.Web.UI.ScriptManager) 
is not compatible with the type of control 
(System.Web.UI.ScriptManager).

I put aside the surprise that a type was not compatible with itself, and checked the source control history. The specific page hadn’t been changed since the last time I’d tried it. I know the project is under active development, including a recent deployment of the latest version at the client site, so I had ever reason to believe the build should work.

Before sending a panicked email to my team, I did a quick Google search. I found a couple links of similar people with this problem in VS2008, but I’m still running VS2005.

I realized, however, that I had installed Framework versions 3.0 and 3.5 since I had last had to work on this project. I went to the project references, and checked that for System.Web.Extensions, and noticed that “Specific Reference” was set to false. I set this to true, rebuilt the project, and started the debugger again.

This time, success! The page displayed as expected.

What problems have you encountered from having multiple .NET Frameworks installed?