Wednesday 7 September 2011

Crashing Extreme WM-200

We've had a couple of instances where an Extreme WM-200 wireless controller will lockup and become unresponsive (though still functional, we can't log on to it), and in each instance we've found it's due to the internal hard disk filling up with log messages (specifically the /var/log/messages file, which should rotate but doesn't). This is pretty easy to fix, but finding out a) the cause and b) how to fix it can be very fiddly, so hopefully this can save someone a frustrating evening.

You'll need to console onto the failed unit and reboot it. We need to get it into single user mode, so when the GRUB screen comes up arrest it by pressing a key, then hit 'e' to edit the GRUB loader. Press 1, to select line 1, then 'e' again to edit it, and add 1 to the end of the line. Then press Enter and hit b to boot the edited loader. This should go through a basic boot cycle, dropping you into a bash shell with just a hash.

From here you can verify if it is indeed a full disk that's causing the trouble, just type df and see if any of the mounts are 100% used.

So far so good, now we need to remount the filesystems so we can clear some space. After much digging in the /etc directory, the following lines should build a usable filesystem for you:



mount -n -t proc none /proc
mount -a -t nonfs
mount -o defaults,noatime,nodiratime /dev/ide/host0/bus1/target0/lun0/part1 /mnt/flash &> /dev/null
mount -o defaults,noatime,nodiratime /dev/ide/host0/bus0/target0/lun0/part2 /original_root/
mount -o defaults,noatime,nodiratime /dev/ide/host0/bus0/target0/lun0/part5 /original_root/var/controller/images
mount -o defaults,noatime,nodiratime /dev/ide/host0/bus0/target0/lun0/part7 /original_root/var/controller/log
mount -o defaults,noatime,nodiratime /dev/ide/host0/bus0/target0/lun0/part6 /original_root/var/controller/log/cdr




From here it's just a simple matter of browsing to the /var/log directory and issuing:


rm -f messages


Type reboot, and you should be good to go.

Friday 19 August 2011

JavaDoc Inheritance

Every so often you come across something so staggeringly simple and useful, yet relatively unknown. In the interests of cutting down the amount of class/method documentation we had to produce, I was researching whether people tended to document methods in interfaces, classes or both. It turns out there is a very elegant solution to give you comprehensive documentation without repeating yourself:

Document the methods in the interface, then inherit the documentation into the class, and provide fixed documentation for any class specific methods.

To let javadoc handle the inheritance from the interface, you can just comment using a tag: {@inheritDoc}. For example:


interface foo {

/**
* documentation!
*/
public void x();
}


class bar implements foo {

/* {@inheritDoc} */
public void x() {
doStuff;
}
}


One thing to note - this doesn't apply to class documentation, only to method documentation.

Tuesday 7 June 2011

OpenSessionInView - Outside the View Pt. II

This update is a followup to my previous article about extending Hibernate Sessions without using OpenSessionInView - Outside the View . in that article, I introduced the idea of using Spring's HibernateInterceptor and Aspect Oriented Programming to wrap objects that would need extended Hibernate support.

That worked fantastically for us, for about 10 minutes, until we realised that Spring's HibernateInterceptor was only capable of weaving beans referenced in the AppContext. We had a definite requirement to weave objects loaded and instantiated at run-time - for instance objects loaded as part of a Quartz scheduled job.

The solution we came up with was a mix of AspectJ and annotations. We defined a simple annotation called SessionManaged:


public @interface SessionManaged {

}


We will use this annotation to mark classes or methods we want to have Hibernate session scope. We then define our own AspectJ aspect, the HibernateInterceptorAdvice :


@Aspect
@Configurable
public class HibernateInterceptorAdvice {

private static Logger logger = Logger.getLogger(HibernateInterceptorAdvice.class);

@Autowired
private SessionFactory sessionFactory;

HibernateInterceptorAdvice() {
}

// Only execute around @SessionManaged annotated methods/objects
@Around("execution(@com.essensys.bluefin.annotations.SessionManaged * *(..)) && !within(HibernateInterceptorAdvice)")
public Object interceptCall(ProceedingJoinPoint joinPoint) throws Throwable {


/** Perform the Pre-execution logic **/
// Fetch new Session
Session session = SessionFactoryUtils.getSession(sessionFactory, true);

// Get Session Holder
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
.getResource(sessionFactory);

// Check for existing session
boolean existingTransaction = (sessionHolder != null && sessionHolder
.containsSession(session));

if(logger.isDebugEnabled())
logger.debug("Existing Session: "+existingTransaction);

// If we have no existing session, create a new one and bind it
if (!existingTransaction) {
if (sessionHolder != null) {
sessionHolder.addSession(session);
} else {
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
}
}


/** Perform the Business Logic call and return it's Value **/
// Now we have an opened session, proceed with the execution
try {

Object retVal = joinPoint.proceed();
return retVal;

// Re-throw any exceptions, but make note in the Aspect
} catch (Exception e) {

if(logger.isDebugEnabled())
logger.debug("Exception Encountered in Aspect",e);

throw e;


/** Perform the Post-execution Logic **/
} finally {

// Check to see if we used an existing session, if so do nothing
// if we used a new session, unbind it.
if (existingTransaction) {

if(logger.isDebugEnabled())
logger.debug("Not Unbinding Existing Session");

} else {

// Close Session
SessionFactoryUtils.closeSession(session);

// Check Session is still bound
if (sessionHolder == null
|| sessionHolder.doesNotHoldNonDefaultSession()) {

if(logger.isDebugEnabled())
logger.debug("Unbinding Session");

// Unbind Session
TransactionSynchronizationManager.unbindResource(sessionFactory);
}
}

}

}

}


The reason we use AspectJ for this is that we can weave target objects at load-time, rather than at run-time like the Spring AOP. To make sure this happens, you may need to download a Spring Instrumented classloader for your application server (see the Spring documentation under Load-Time Weaving), and you'll need the following in your AppContext:


<context:component-scan base-package="pkg" />
<context:annotation-config/>

<context:load-time-weaver/>
<context:spring-configured/>


And you'll need to create an aop.xml file in your META-INF directory that will map out your aspects and define which classes in the package are to be weaved:


<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-verbose ">
<!-- only weave classes in our application-specific packages -->
<include within="pkg.console..*"/>
</weaver>

<aspects>
<!-- weave in just this aspect -->
<aspect name="pkg.HibernateInterceptorAdvice"/>
</aspects>
</aspectj>



When a weaved class is loaded, either at run-time or at load-time, this setup should take care of the Hibernate session. If there is an existing one, it will use that, if not it will create a new one, and close it after the execution of the annotated method.

Thursday 6 January 2011

OpenSessionInView - Outside the View

OpenSessionInView is a well known session management pattern, used to open and close sessions in a web applicaiton at the start/end of an HTTP session. This assumes that the HTTP session actually represents a viable unit of work, and as such it allows things such as Object Relational Mapping managers to work within a single session for the duration of the user's HTTP session. Why would this be necessary? The key driver in my work for using OpenSessionInView has been the use of Lazy Initialization for Hibernate relationships. For instance, Object A has a relation to a set of Object B. Loading Object A through a Hibernate DAO is fine. But passing Object A to Object C, which then tries to call A.getB(), will throw a LazyInit exception with a 'no session' error. Using OpenSessionInView allows the same session to be used for the duration of the HTTP request that triggered this set of work, meaning that you can lazily load any depth of relationships (A.getB().getD().getE()... ) without worrying. Of course, you could always just tell all of your relationships to Eagerly load, but if you have a tightly related data model you may well end up loading your whole database into memory everytime you pull an object from a DAO.

So OpenSessionInView works very nicely with servelet/HTTP based systems, and it is very easy to set up in Spring, there's loads of documentation on line, and at its core it just needs you to add a Servlet Filter to your web.xml :


<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>



But what if the actions you want to take are not initiated by a request from the View? In that case, a servlet filter can't help - it will never be fired by the filter chain as there's never a servlet called! What we need is a way to wrap our Session around a particular chain of execution. Some areas that I have come across this requirement are when calling some functionality at load time (usually during development), and when calling functionality through a scheduling API like Quartz. In these cases, we will get Session errors due to lazy loading even though our OpenSessionInView filter is working fine.

Thankfully Spring provides a variation on the Servlet filter that can be applied as an Aspect to any given Object, without needing any re-coding, and without needing to roll our own session handling code in any business object that needs this functionality. This is called the OpenSessionInView Interceptor, and is functionally the same as the servlet filter. To do this, you'll need to add two new beans to your app context:


<bean id="hibernateInterceptor"
class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>

<bean id="autoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<idref local="hibernateInterceptor" />
</list>
</property>
<property name="beanNames">
<list> <!--this proxies every bean with the specified pattern -->
<value>testbean</value>
</list>
</property>
</bean>


The first object, HibernateInterceptor, creates the Aspect itself. This does assume you are using Hibernate 3. The second is a Spring AutoProxyCreator. Essentially, this bean takes a list of bean names to proxy, which can be explicit names or patterns to match. For each, when instatiated it wraps the bean in a proxy object, to which it applies the HibernateInterceptor. This effectively binds the Hibernate Session for the lifetime of that proxied Bean, allowing it to operate as though it had been invoked through an OpenSessionInView handled Servlet.