Posted by Tejus Parikh on January 05, 2011
The title of the post is just a little mis-leading. We’re not going cable free, we’ve been so for more than 3 years. I just felt compelled to write this post now because I finally have a setup that I like and is easy to use.
Read the full post »
Posted by Tejus Parikh on January 16, 2011
At my current employeer, we’re starting to reach the point where we need a messaging infrastructure to scale our product. The traditional Java approach is to use a JMS broker, such as ActiveMQ. However, there’s a new alternative API in the form of AMQP. Our first use-case is a fan-out queue and I took the opportunity to see how the solution would look using both API’s within Spring. You can find the code for my proof of concept on Github. I’ve only included the most relevant snippets in the post, so for a real understanding on how to configure everything, look through the source.
ActiveMQ
The heavyweight in open source Java Messaging is ActiveMQ. ActiveMQ is a traditional JMS solution. Spring provides a template class that abstracts the communication with the JMS provider. The template requires a JMS connection factory along with a destination name. The same connection factory can be used for both sending and receiving messages by classes in the same JVM. The relevant configuration bits are as follows:
This creates a destination queue, a connection factory with the host and the template for the producer. In this example, the consumer is configured as a
MessageListener
and therefore, does not need a template.
The
StatMessageConverter
is a bean that converts the payload to and from JSON. I choose to send the messages as JSON since we have a multi-language infrastructure and JSON makes it easier for those diverse systems to communicate.
With this configuration, sending a message with a JSON payload is as simple as:
template.convertAndSend(message);
The consumer configuration is simpler. Since my consumer class implements
MessageListener
, I just need to create a
listener-container
and inject the bean:
Whenever the producer sends the message, the
onMessage
method of the consumer will be called by Spring.
AMQP
AMQP with Spring works much the same way. There is a template and a connection factory. However, AMQP is different than JMS. First AMQP is a wire-level protocol, whereas JMS is an API. Therefore, different AMQP implementations should be able to communicate with each other. Secondly, the paradigm is slightly different. In JMS, there is a queue and consumers and producers bind to that queue. In the AMQP world, producers talk to exchanges and consumers bind queues to those exchanges. Therefore the communication topology is fully within the configuration and is unknown to the code, making it trivial to go from a one-to-one exchange to a fan-out.
The AMQP provider that made the most sense was
RabbitMQ. RabbitMQ is a logical choice because it has first-party java libraries and is owned by VMWare, who also own Spring, which bodes well for the project’s future.
Spring’s AMQP support requires a little more configuration compared to the JMS solution, but the basics are the same. You need connection factory, template, and a listener.
The first difference is that there must be an administration bean:
Next the send template needs both the routing key and the exchange:
The
statsExchange
will create the exchange as part of it’s initialization. If the exchange already exists, it will bind to it.
Next comes the creation of the Queue:
Since I want fan-out behavior, each consumer must have a unique queue name. Therefore, I use an
instanceID
instead of a configured property. Otherwise, the same rule for exchanges applies here, the consumers will just listen on the existing queue.
The consumer is similar, but in this case we can use a regular Pojo. Since Spring’s AMQP support includes marshalling support for JSON, no special conversion needs to occur on the client side:
All that remains is binding the exchange to the queues:
Sending a message is identical to JMS:
template.convertAndSend(message);
Conclusions
This little exercise was interesting because it shows that from the programmer’s perspective, there is little difference between using AMQP or JMS. With a little care in interface design, the two solutions can be swapped with minimal development effort.
For our needs, we decided to go with RabbitMQ. The solution just feels simpler for the different types of communication we need. Plus the use of an Erlang message broker feels like the right technology for the right problem.
Read the full post »
Posted by Tejus Parikh on January 17, 2011
I was just reading this article found on Hacker News about the development process at facebook.
The line I liked the most was:
Read the full post »
Posted by Tejus Parikh on February 12, 2011
Unfortunately, I’m back to developing Flex applications and mostly been focused on the communication layer between our Flex application and the Java backend.
Adobe’s BlazeDS product is the easiest way to communicate between a Flex client and a Java backend. BlazeDS integrates cleanly with Spring, has annotations to expose methods as services and integrates directly with Spring security. However, like most Flex features, it has it’s quirks.
Our model objects follow the Fluent Interface pattern and we make use of method chaining to remove some of the code clutter when setting multiple properties. Furthermore, our object models are interfaces since the representations may be pulled from a large variety of backend stores. Of course, this doesn’t work with the Blaze DS serialization. This post is about all the wrong ways to do this and the explanation for why it doesn’t work. I cover my solution at the end.
The (Simplified) Java Model
// net.vijedi.java.User
interface User {
String username();
}
// net.vijedi.java.HibernateUser
@Entity
class HibernateUser implements User {
@Column
private String username;
public String getUsername() {
return username;
}
public User setUsername(String name) {
username = name;
return this;
}
}
Mapping to ActionScript in all the Wrong Ways
My first attempt was to map the AS object to the interface
User
// net.vijedi.as.User
[RemoteObject(alias="net.vijedi.java.User")]
class User {
public var username:String;
}
Inspecting the
event.result
returned in the Blaze DS callback showed that the framework had converted it to a AS
User
object. However, the username property was
null
. Changing the metadata to
[RemoteObject(alias="net.vijedi.java.HibernateUser")]
yielded the same result. Likewise, changing
[RemoteObject]
simply returned an empty
ObjectProxy
.
The problem is in using the fluent interface pattern. Blaze DS requires the object to follow
Java Bean schematics. This means that setters must not have a return type.
Changing the
net.vijedi.java.User
interface to follow bean schematics didn’t have the desired effect. The ActionScript side showed an
ObjectProxy
with the correct values set. Blaze DS sends the concrete type information as part of the return. It will still create the object, but it will not be what you want. Since AS is not a duck-typed language
event.result AS User
will throw a runtime exception.
The Only Way to Do It
Changing the Java class to:
class HibernateUser implements User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String name) {
username = name;
}
}
and the ActionScript class to:
[RemoteObject(alias="net.vijedi.java.HibernateUser")]
class User {
public var username:String;
}
This actually worked. The end result is that if you would like to use Blaze DS’s mechanisms for object serialization, the best bet is to create a set of custom value objects that are used for communication. This prevents serialization failures resulting from changes to the underlying models and frees the rest of the interfaces from being tightly coupled with the front end.
One Last Note about Booleans
If you have a field named
boolean isEnabled
, most IDE’s will create the getter
boolean isEnabled(){...}
. However, Blaze DS doesn’t remap it back the same way and the Actionscript side needs to be
var enabled:Boolean
, without the “is.”
Read the full post »
Posted by Tejus Parikh on March 29, 2011
Finally a Rails post! This one is short, basic, and probably has a bunch of other examples on the net.
Rails3 escapes HTML by default, so this isn’t strictly necessary, but I still believe that what goes into the datastore should be clean. After all, the data will probably last longer than the front-end.
I found this post that explains how to do it for your ActiveRecord
models. However, I don’t have columns. Instead I used the following before_filter
in my model class.
before_save :sanitze_html
def sanitze_html
@attributes.each_key do |attr|
value = @attributes[attr]
if(value.class == String)
@attributes[attr] = strip_tags(value)
end
end
end
It’s the same idea, but instead use the attribute map to pull the objects out. If it’s a
String
type, call
strip_tags
.
Read the full post »
Posted by Tejus Parikh on May 18, 2011
One of the challenges of working on a large system with multiple developers is the management and handling of application errors and exceptions. Often, developers get frustrated with managing typed exceptions and all interfaces either throw or catch Exception. Another common approach is to change all exceptions to RuntimeException to avoid cluttering interfaces.
An alternative approached is described in this paper by Andy Longshaw. His approach breaks exceptions into two distinct hierarchies, domain and system. Domain errors caused by logical faults in the application, such as a zero being passed as a divisor to a function. System errors are errors caused through the interaction with other components, like a network timeout when attempting to communicate with the database. Both exception types are checked exceptions, which means they must be caught and handled by each layer of the application. He presents guidelines on when and at which layer each type of exception should be logged.
If you are using Java the obvious drawback of using checked exceptions everywhere is that each layer will be filled with code that looks like the following:
try {
service.doApiCall();
} catch(DomainException e) {
log.error("Domain exception occurred", e);
} catch(SystemException e) {
log.error("System exception occurred", e);
}
The duplication of handling of api exceptions can easily be handled with a custom annotation and Spring AOP.
The first step is to create the Boundary logging annotation. This annotation describes where exceptions should be logged.
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD})
public @interface BoundaryLogger {
}
Next, we need to create the interceptor. Along with just logging exceptions, I also choose to log the api calls. There are a few steps to creating an Aspect that can be used by Spring-AOP.
First added the
@Aspect
annotation to the class declaration.
@Service // make this available as a spring bean
@Aspect // tell spring this class is an aspect
public class BoundaryLoggingInterceptor {
Next, create a method that tells the Aspect to do something before the underlying method, annotated with
@BoundaryLogger
, is called. In this example, it’s to log the method invocation.
@Before("@annotation(net.vijedi.springlogging.interceptor.BoundaryLogger)")
public void logInvocation(JoinPoint jp) {
Similarly, triggering the aspect at method end can be handled with:
@AfterReturning(
pointcut = "@annotation(net.vijedi.springlogging.interceptor.BoundaryLogger)",
returning = "retVal")
public void logComplete(JoinPoint jp, Object retVal) {
The one we are especially interested in for this purposes of this blog post is exception logging. This is the entire method for logging exceptions:
@AfterThrowing(
pointcut = "@annotation(net.vijedi.springlogging.interceptor.BoundaryLogger)",
throwing = "ex"
)
public void processException(JoinPoint jp, Throwable ex) throws SystemException, DomainException {
if(ex instanceof SystemException) {
// System exceptions were logged at source
// do not log the exception, just the return
logReturn(jp, getLog(jp));
throw (SystemException) ex;
} else if(ex instanceof DomainException) {
logException(jp, ex);
throw (DomainException) ex;
} else {
logException(jp, ex);
throw new DomainException(ex);
}
}
The
logException
method is very simple:
private void logException(JoinPoint jp, Throwable ex) {
Log log = getLog(jp);
log.error(ex.getMessage(), ex);
logReturn(jp, log);
}
How the
logger
is obtained is very important for accurate logging. Otherwise, it will appear that all logging messages are coming from the interceptor and not from the underlying method. Along with the confusion this could cause, it will also make it harder to use automatic log analyzers. However, it is very easy to get a logger in the context of the underlying class.
protected Log getLog(JoinPoint jp) {
return LogFactory.getLog(jp.getTarget().getClass());
}
Once the Aspect has been created, the final step is to tell spring what to do when it encounters the annotation
@BoundaryLogger
.
There are four steps, tell spring to use annotations to configure the environment, to scan the packages the annotations are in, and to create the aop environment.
This is all that’s need to use annotations for logging at the tier boundaries. The complete code for the example is available at my
Spring Boundary Logging repo on Github.
Read the full post »
Posted by Tejus Parikh on June 09, 2011
I just had to make the rather painful (well painful for my free time) decision to re-write the project that I and a team member had written in Vaadin with the old standby’s of JQuery, JSP’s, and Spring MVC. There was a lot of frustration that went into maintaining the project over the last year and it simply became very difficult to deliver what the product team wanted in a timely manner. The point of the post is not to bash the framework, but present the difficulties I encountered that made it unusable for us. I described the reasons we picked Vaadin in a previous post Vaadin. Many of the benefits still exist, but some of our core assumptions lead to major headaches down the line.
Read the full post »
Posted by Tejus Parikh on October 02, 2011
Last week, I searched rather fruitlessly for a way to import my wordpress blog into Tumblr. There were a few snippets and examples out on the web, but they all used the older API or required email addresses and passwords for authentication.
Read the full post »
Posted by Tejus Parikh on October 07, 2011
On a recent trip through our code base, I realized that there were multiple projects that used identical properties defined in files that sat on the file system. I find DRY is a superior pattern to copy and paste I wanted to consolidate these into a single location.
Read the full post »
Posted by Tejus Parikh on October 19, 2011
Read the full post »
Posted by Tejus Parikh on November 05, 2011
One challenge of the maven way is how to sensibly version dependencies in a large, but constantly changing, project.
Read the full post »
Posted by Tejus Parikh on November 22, 2011
Can Vertical Acuity Stop Your Site Losing Visitors?It’s always fun to wake up in the morning and see Mashable do a write up on your company.
Read the full post »