Name: Password:

June 13, 2013

Contributing to GitHub hosted Open Source Projects through Pull Requests: A Checklist

So there is an open source project on GitHub. And you forked it already. And there is this bug XYZ you would like to fix, throught a pull request. Here is a short checklist how you can do it.

Use Feature Branches

Get ready to work with feature branches. Those isolate the work you do for a particicular pull request from all the other things you want to contribute.

Create a branch for the issue XYZ where you will implement the bug fix.

git checkout master        # starting point is your master
git checkout -b XYZ        # create and checkout branch XYZ
                           # you are going to work on

Do non-stop coding. All day all night. Mind coding styles of the project you are working on. Use the right tools.

At some point you are done.

git log                    # check what you have done

Cleanup using git rebase

You may have produced several commits. And there may be typos in your commits. Or you commited try to fix bug (1..n). Squash (i.e. combine) all of your commits and give it a nice commit message. This makes it easier for reviewers to see the actual changes and to eventually merge the pull request.

Your tool for the job is interactive rebase. It allows you to reword, remove, combine and alter commits.

git rebase -i HEAD~n	     # n=number of commits from HEAD
                             # you created

This pops up an interactive console

pick 906eb32 yea, nearly done
pick 8a45bb9 ok, late night trying again
pick b86deaf got ya

Combine all of your commits into one by assigning s or squash as the rebase operation.

pick 906eb32 yea, nearly done
s 8a45bb9 ok, late night trying again
s b86deaf got ya

Finish the job, i.e. press [ESC], [:wq] to write the changes and close the editor.

You will be asked to write a commit message that describes everything you did. Make it a good one (check your projects contribution guidelines, too).

Again, finish the job with [ESC], [:wq].

You are done and your changes are ready to be published!

Push, Pull Request, restart

Push the stuff to your remote:

git push origin XYZ

If you have pushed parts of the work before, you may need to override these changes by applying force (-f):

git push -f origin XYZ      # overrides history on the server
                            # branch so take care what you do

Create a pull request from your origin/XYZ branch to the OSS projects development branch.

Switch back to your master branch

git checkout master

And create a new feature branch for this AABB issue you wanted to fix for such a long time already.

git checkout -b AABB

There is more

There exist many more resources worth checking out on the topic:

March 24, 2013

Camunda BPMN 2.0 Modeler Introduction

Do you want to create and refactor BPMN 2.0 without pain?

Check out the introduction on the Camunda Modeler, a tool I have mainly been working on in the last month. The modeler is open source as part of our camunda BPM platform.

Can be downloaded, too.

March 24, 2013

Using STFU powers to deal with Ruby version upgrades

... or how to spend unneccessary time on infrastructure problems.

Ruby is a great language and offers many tools to quickly develop (web) applications and awesome libraries. But sometimes it sucks. And that is the case when migrating applications to new Ruby versions.

The last weekends I worked on switching my Ruby on Rails 2.x applications from Ruby 1.8 to Ruby 1.9. One thing I learned is that Ruby 1.9 uses UTF-8 for file encoding now. Rails 2.3 applications and libraries (e.g. the mysql gem) have a number of issues with that, different ones depending on the platform you are running ruby on. This is a non-complete list of things to care about when updating.

Encoding update

To start with, Ruby uses the LANG environment variable to determine file encoding. So make sure you have it set to a UTF-8 locale on your system.

 irb(main):001:0> ENV['LANG']
 => "en_US.UTF-8"

Next, make sure that you do not use any special NON-ASCII characters (åößè are good candidates) in mail templates because the action-mailer gem for Rails 2.3 does not quite seem to understand UTF-8 yet.

Also, make sure your source files are UTF-8 encoded (adding the # encoding: utf-8 header may be required, too). And then, instruct your rails application to use UTF-8 as the default encoding:

# add to top of config/environment.rb
Encoding.default_external = Encoding.default_internal = Encoding::UTF_8

If you use regular expressions, do not wonder why they don't match anymore. They just don't because you may not have solved all encoding problems yet.

After encoding

You are done with encoding problems now and want to use all the latest UTF-8 compatible gems now? Reconsider. Then make sure to stick to the 1.x version of rubygems. Because rails 2.3 does not like the 2.0 versions of the gem.

Check your database connectivity library (I used the mysql gem for Ruby 1.8). The mysql gem has encoding issues on Linux systems, so switching to the mysql2 gem is inevitable. Only versions < 0.3 work though. Just because. If you are on windows stick to the mysql gem for now. Because mysql2 gives Bad file descriptor errors.

Remove deprecation warnings

Use Object#tap instead of #returning. Looks awful in code but prevents your server log from getting spammed.

Think about monkey patching your Rails 2 app for some more UTF-8 compatibility or switch directly to Rails 3.

Finally

Drink a coffee, eat a muffin and read about others going through the same kind of stuff, some even spending month to do it.

September 24, 2012

Master thesis finished

Finished my master thesis entitled Exploring Run-time Behavior in Reversible Experiments - An Application of Worlds for Debugging. It is about painting walls and refrigerators. From the abstract:

Debuggers are often used to inspect running software systems in order to support the understanding of source code. They differ substantially from most tools that visualize run-time data as they make it possible to keep track of a running program as it executes. Thereby they encourage learning through experience. At the same time, conventional debuggers do not properly support incremental understanding. The reason is that they offer only limited options to safely re-explore a particular run-time behavior without restarting the program under observation.

Against that background, this work examines Worlds [44]—a language extension that allows for scoping of side effects in imperative programming languages. The thesis evaluates the concept of Worlds to isolate side effects caused during debugging. By doing so, the effects of prior explorations can be discarded and the examination of run-time behavior gets safe to be repeated until it yields the desired knowledge gain.

In the course of this work, we present the principle application of Worlds to enable debugging in reversible experiments. Furthermore, we propose a general purpose Worlds mechanism for Squeak/Smalltalk, which is necessary to evaluate the practical application of the concept for Smalltalk. In the course of the evaluation, we present a debugger that employs the mechanism to realize the safe re-examination of behavior inside a debugging session.

September 5, 2011

A jQuery plugin for bootstrap modal boxes

Bootstrap is a CSS toolkit made by two guys at Twitter which kick-starts website development.

Along other gimmicks it offers modal boxes for which I have created a jQuery plugin, Dialog Two.

Check it out.

Fork me on GitHub

July 5, 2011

Spring might say uuuh if you use JPA and throw Exceptions in nested @Transactional contexts

In my Jersey + Spring + JPA stack I recently came across an interesting issue: Throwing an exception inside a @Transactional annotated Spring bean method would cause a org.springframework.transaction.UnexpectedRollbackException in the outer container. The result was that the request ended screwed up and the following stack trace appearing on my application server logs:

org.springframework.transaction.UnexpectedRollbackException: JPA transaction unexpectedly rolled back (maybe marked rollback-only after a failed operation); nested exception is javax.persistence.RollbackException: Error while commiting the transaction
Caused by: 
  javax.persistence.RollbackException: Error while commiting the transaction
  ...

After doing some research, it got apparent that, while there were many varieties, many people had this issue. Some said this was due to limitation in JPA's exception hierarchy, others just claimed it is a Spring or Hibernate or whatever bug.

Wondering, why everyone pointed on the issue, no solved it I created a small test case to investigate what is actually happening.

Test Setup

At first, I got the NewsManager which does some database action when asked to #aggregateNews. If it finds an error, it will throw an exception which itself makes the changes rolled back (pretty clear so far).

@Component
public NewsManager {

  @Transactional
  public News aggregateNews(Date date) {
    // Does some random action here
    // e.g. updating stuff in the database
    
    // May throw a (unchecked) operation failed 
    // exception on error, rolling back the transaction
    if (error) {
      throw new OperationFailedException(
                    "Could not aggregate due to error");
    }
  }
}

The root controller of my Jersey application (a Spring bean, too) will ask the NewsManager to aggregate news and will catch the expected exception in case one is thrown. The reason for choosing this two-layer approach is that roll-backs can cleanly be done without propagating an exception to the presentational layer.

@Path("/")
@Component
public RootController {

  @Inject
  private NewsManager newsManager; // Spring bean
   
  @GET
  @Transactional
  public Object news() {
    try {
      // Call Spring bean
      return newsManager.aggregateNews(new Date()); 
    } catch (OperationFailedException e) {
      return null;
    }
  }
}

What happens when a OperationFailedException is thrown is that this exception will be wrapped nicely with a javax.persistence.RollbackException and then with a org.springframework.transaction.UnexpectedRollbackException and so forth. Your application is not be able to handle it and you read the above mentioned stack trace in your server logs.

Problem deduction

The actual cause of the problem is not the badness of the exception thrown, but the fact that the previous example used nested @Transactional contexts to handle the business logic. Both, the controller and the news bean had @Transactional annotations specified on their business methods. Thus they were instrumented by Spring to use transactional logic.

@Path("/")
@Component
public RootController {
  
  @GET
  public Object news() {
    try {
      // Call Spring bean
      return newsManager.aggregateNews(new Date()); 
    } catch (OperationFailedException e) {
      return null;
    }
  }
}

If you simply remove the outer @Transactional annotation (which might be unnecessary anyway) everything works fine.

Conclusion

I am not convinced, that the above fix may help everyone posting about UnexpectedRollbackException and Spring + JPA. Neither am I hundred percent sure why this happens. What I got is that deliberately throwing exceptions inside nested transactional contexts may not be good for your Spring + JPA applications. Too many miracles happen there, eventually screwing things up and stealing one day of your time to figure out what and why.

November 20, 2010

An MVC extension for Jersey

Nearly every modern web framework features MVC, the separation of program parts into model, view and controller. This article discusses how Jersey, the reference implementation of JSR 311 (JAX-RS) can be extended to do MVC as supported by Ruby on Rails, Spring MVC and many other web frameworks, too.

MVC, what is it?

When talking about MVC in the context of web development the controller is typically the object which is responsible for processing the request in one of its methods (sometimes referred to action invoked on controller).

The controller will return one or more objects containing the result of this process, the so called model. The model is not tied to any graphical representation — it merely acts as a container for the computational results returned by the controller.

A view however gives a model its graphical form. Typically it is written in some kind of markup language to produce HTML (or any other kind of output) from the model.

And in Jersey?

Jersey is the reference implementation for JAX-RS áka JSR 311. As such, it (simply|beauti)fies the development of REST-ful web applications with Java.

It provides MVC to ease application development, however its approach differs slightly from what is considered standard in web development.

Given that a controller c processes a request in one of its methods m most web frameworks will choose a view based on the controller name and the invoked method. The resulting view the framework will use to display the model is based on both, controller and executed method inside the controller (action). In most cases, a web framework might search for the view found as [c]/[m] in a given directory.

In contrast, JAX-RS connects the view to the model without considering the executing controller at all: The graphical representation (XML/JSON/HTML) of a model depends only on the model itself and the mime type requested by the client. Consequently Jerseys way of doing MVC does not consider the controller when selecting a view, too. Considering the JAX-RS philosophy this makes perfectly sense.

However when trying to develop classical web applications this approach seems a bit inappropriate: When a request is processed by UserController#info, which returns an instance of com.sample.User Jersey will try to allocate a view com/sample/User/index.jsp. The same happens if a user gets logged in (done by UserController#info) or if he wants to change his profile (called by UserController#editProfile). All requests will yield the same view, no different functionality can be provided to the user.

Fortunately we can adapt this behaviour by implementing our own MVC component which we will then plug in into Jersey.

Implementing a MVCViewMessageBodyWriter

To extend Jersey to support selecting views based on controller and executed action we can plug into Jerseys view provider mechanism. This is as easy as defining a class annotated with @Provider which implements MessageBodyWriter. A stub for the class can look somewhat like this:

@Provider
@Produces("text/html")
public class MVCViewMessageBodyWriter implements
  MessageBodyWriter<Object> {
  
  @Override
  public boolean isWriteable(
    Class<?> type, Type genericType, 
    Annotation[] annotations, MediaType mediaType) {

    // TODO: Check if view like [controller]/[action].jsp
    // exists under /WEB-INF/views
  }

  @Override
  public void writeTo(
    Object o, Class<?> type, Type genericType, 
    Annotation[] annotations, MediaType mediaType,
    MultivaluedMap<String, Object> httpHeaders,
    OutputStream out) throws IOException {

    // Redirect to view placed in 
    // /WEB-INF/views/[controller]/[action].jsp
  }

  @Override
  public long getSize(
    Object o, Class<?> type, Type genericType, 
    Annotation[] annotations, MediaType mediaType) {
    
    // Return -1 to indicate that no explicit 
    // content lenght can be assigned 
    // (frankly, we do not know about the length)
    return -1;
  }
}

Implementing the interface MessageBodyWriter<Object> tells Jersey that, whenever an instance of Object should be rendered to the client, MessageBodyWriter#isWritable should be called by Jersey to check if the writer can write the specified object. If that is the case, MessageBodyWriter#writeTo will be invoked by the framework and the writer should write the body to the passed output stream. Optionally the writer may specify the size of the output data in MessageBodyWriter#getSize.

Nasty details

Our MVC implementation will check in MVCViewMessageBodyWriter#isWritable, if there exists a view to display for the current controller / action. Inside the writer it could do so by invoking

private String getViewPath(HttpContext context) {
  AbstractResourceMethod m =
    context.getUriInfo().getMatchedMethod();

  String controller =
    m.getMethod().getDeclaringClass().getSimpleName();
  String action = m.getMethod().getName();

  if (controller.endsWith("Controller")) {
    controller = controller.substring(0, 
      controller.length() - "Controller".length());
  }

  controller = controller.toLowerCase();
  
  String path = "/WEB-INF/views" + 
                controller + "/" + action + ".jsp";
  return path;
}

in conjunction with

public boolean templateExists(String path) {
  try {
    return servletContext.getResource(path) != null;
  } catch (MalformedURLException e) {
    // TODO: log
    return false;
  }
}

The required writer attributes context and servletContext can be automatically injected into the writer using Jerseys @Context injection mechanism:

// Injecting both HttpContext and current ServletContext into
// the writer... 
@Context
private HttpContext context;

@Context
private ServletContext servletContext;

In the MVCViewMessageBodyWriter#writeTo method the servlet contexts dispatch mechanisms are used to forward the request to our view:

// way to obtain request via @Context injection
@Context
private ThreadLocal<HttpServletRequest> requestInvoker;

// way to obtain response via @Context injection
@Context
private ThreadLocal<HttpServletResponse> responseInvoker;

private void dispatch(Object model) throws IOException {
  String viewPath = getViewPath(context);

  RequestDispatcher d =
    servletContext.getRequestDispatcher(viewPath);

  if (d == null) { /* could not be obtained */ }
  
  HttpServletRequest request = requestInvoker.get();
 
  // Set model to be accessible as it variable in view
  request.setAttribute("it", model); 
  try { 
    d.forward(request, responseInvoker.get());
  } catch (ServletException e) {
    throw new RuntimeException("Dispatch to view failed", e);
  }
}

The final product

That's it! Putting all the pieces together, our do-MVC-as-other-frameworks-do-it-MessageBodyWriter looks like this:

@Provider
@Produces("text/html")
public class MVCViewMessageBodyWriter implements
        MessageBodyWriter<Object> {

    // Injecting both HttpContext and current ServletContext into
    // the writer...
    @Context
    private HttpContext context;
    @Context
    private ServletContext servletContext;

    // way to obtain request via @Context injection
    @Context
    private ThreadLocal<HttpServletRequest> requestInvoker;

    // way to obtain response via @Context injection
    @Context
    private ThreadLocal<HttpServletResponse> responseInvoker;

    private void dispatch(Object model) throws IOException {
        String viewPath = getViewPath(context);

        RequestDispatcher d =
                servletContext.getRequestDispatcher(viewPath);

        if (d == null) { /* could not be obtained */ }

        HttpServletRequest request = requestInvoker.get();

        // Set model to be accessible as it variable in view
        request.setAttribute("it", model);
        try {
            d.forward(request, responseInvoker.get());
        } catch (ServletException e) {
            throw new RuntimeException("Dispatch to view failed", e);
        }
    }

    @Override
    public boolean isWriteable(
            Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        // Check if view like [controller]/[action].jsp
        // exists under /WEB-INF/views

        return templateExists(getViewPath(context));
    }

    @Override
    public void writeTo(
            Object o, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream out) throws IOException {

        // Redirect to view placed in
        // /WEB-INF/views/[controller]/[action].jsp

        dispatch(getViewPath(context));
    }

    @Override
    public long getSize(
            Object o, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        // Return -1 to indicate that no explicit
        // content lenght can be assigned
        // (frankly, we do not know about the length)
        return -1;
    }

    private String getViewPath(HttpContext context) {
        AbstractResourceMethod m =
                context.getUriInfo().getMatchedMethod();

        String controller =
                  m.getMethod().getDeclaringClass().getSimpleName();
        String action = m.getMethod().getName();

        if (controller.endsWith("Controller")) {
            controller = controller.substring(0,
                    controller.length() - "Controller".length());
        }

        controller = controller.toLowerCase();

        String path = "/WEB-INF/views"
                + controller + "/" + action + ".jsp";
        return path;
    }

    public boolean templateExists(String path) {
        try {
            return servletContext.getResource(path) != null;
        } catch (MalformedURLException e) {
            // TODO: log
            return false;
        }
    }
}

Voilà!

Don't forget to put this provider class somewhere where Jersey can find it (specify package scanning accordingly).

More Resources

November 11, 2010

Solving Hibernate AssertionFailure: collection [n-side] was not processed by flush()

When it comes to m:n relations Hibernate throws around AssertionErrors when an entity on the m side of the relation changes its relation to one or more ns.

Considering our test setup

@Entity
class Article {

    @ManyToMany
    private List<Topic> topics;

    public List<Topic> getTopics() {
        return topics;
    }
}

@Entity
class Topic {

    @ManyToMany
    private List<Article> articles;

    public List<Article> getArticles() {
        return articles;
    }
}

Now let us consider the following code snipped and assume that the entity manger denoted by em is implemented by Hibernate.

// Assume a persistence context (or an open transaction)
// here
Article a1 = new Article();
Topic t1 = new Topic();
Topic t2 = new Topic();
Topic t3 = new Topic();

a1.getTopics().add(t1);
a1.getTopics().add(t2);

em.persist(a1); // lets say topic persistence is cascaded

// We want to remove the previously added 
// and a new topic is added
a1.getTopics().clear();
a1.getTopics().add(t3); 

em.flush(); // lets push a1 to database
  
// yields org.hibernate.AssertionFailure: collection [Topic.articles] was not processed by flush()

The failure is not a programmer bug (what should be wrong with that code?) but a serious issue with Hibernate. By the way present since 2007 according to the JIRA entry on the hibernate bug tracker.

I wonder if non of the Hibernate guys uses m:n relations in his programs. Grails people apparently do, as Julien Dubois stated in his comment on the issue. They propose a fix which actually works in my production setups for Hibernate on Glassfish (note that there is another workaround, too which however only works on JBoss application server).

Basically the patch replaces the Hibernate flush event listener with a custom one which is able to handle m:n relations properly.

public class PatchedEJB3FlushEventListener 
                 extends EJB3FlushEventListener {

    private static final Logger LOG = 
        Logger.getLogger("PatchedFlushEventListener");

    @Override
    protected void performExecutions(EventSource session) 
        throws HibernateException {

        session.getPersistenceContext().setFlushing(true);
        try {
            session.getJDBCContext()
                   .getConnectionManager().flushBeginning();
            // we need to lock the collection caches before
            // executing entity inserts/updates in order to
            // account for bidi associations
            session.getActionQueue().prepareActions();
            session.getActionQueue().executeActions();
        }
        catch (HibernateException he) {
            LOG.log(Level.SEVERE, "Could not synchronize database state with session", he);
            throw he;
        }
        finally {
            session.getPersistenceContext().setFlushing(false);
            session.getJDBCContext()
                   .getConnectionManager().flushEnding();
        }
    }
}

Compared to the original code the only magic it does is telling the persistence context about the flush

session.getPersistenceContext().setFlushing(true);

To get this working you have to tell hibernate about the new event listener by adding the property hibernate.ejb.event.flush to persistence.xml or hibernate.cfg. I added

<property name="hibernate.ejb.event.flush" value="de.nixis.commons.hibernate.PatchedEJB3FlushEventListener" />

to my persistence.xml and it worked. BÄM!

Bottom line: I patched the EJB3FlushEventListener instead of the DefaultFlushEventListener to make the stuff work in a JPA environment and am now able to run Hibernate (bug fixed) + Glassfish in a production environment.

August 13, 2010

Business studies explained: Macroenvironment

This series explains some typical terms from business studies in a way software engineers can understand.

Today: What is a macroenvironment?

#ifdef env
  <-- macroenvironment
#ifndef env
  <-- also here
#endif

August 11, 2010

Creating own server profile in JBoss AS 5 and 6

Recently I tried to figure out how to shrink my JBoss AS 5 server installation in order to remove its huge memory footprint. I wondered how it can be that it eats 80% of my servers available main memory.

What I want my JBoss to be able to is to provide the functionality described in the EJB 3.1 lite profile plus deployments of ears. How can I achieve this?

An inherent problem with JBoss is that it comes bundled with a big number of libraries (no one needs). Instead of being able to add libraries in a modular fashion (such as adding reliable messaging if I need it) all libraries are wired into the server.

Yes, there are profiles in JBoss which provide a subset of the functionality. But what is in them? Default, standard, all include unnecessary messaging stuff. Minimal includes no EJB 3 at all. In between an application server administrator has to cobble together a bundle suited to his needs either by extending the minimal profile or shrinking the all or default profile. As none of the JBoss modules (or libraries) have a dependency description this results in a try-and-error task. Can be? No, there have to be people who know how to do it.

As there is no documentation for this on the web, I asked the question at stackoverflow and got a good answer. The JBoss shrinking mystics are explained in this article in the JBoss community wiki.

The steps described there actually worked and I was able to shrink the memory footprint of the application server from 400MB to 300MB. Along with that the startup time decreased from 45s to 25s.

About

I'm Nico Rehwaldt, a software engineer from Berlin (Germany). On this website I talk about issues of the web, open source and my own projects.

Archive

2010

2011

2012

2013