Saturday, August 9, 2014

Preventing NPE when creation Option

Sometimes you don't know whether values are present and you want to use an Option to represent that posibility. While Scala API's often support returning an Option, this is not so when integrating with Java. You might want to get a value somewhere from an object hierarchy like this:
user.getAddress().getStreet()
Since you might expect a value is not present, you want to wrap this in an Option. However, if either 'user' or 'address' is null, Option will throw a NPE.

To guard against this, you want to catch any NPE and return a normal None. However, the Option trait is sealed so it is not possible to extend it. Here is a solution how it can be done by using an object with an 'apply' method. This SafeOption returns a normal Option (Some or None), but catches any NPE and returns a None in that case.
/**
 * A 'safe' type of Option which catches any exception, so also NPE's
 * when creating the option.
 * So 'SafeOption(null.name)' will return None.
 */
object SafeOption {

  def apply[A](value: => A): Option[A] = try {
    Option(value)
  } catch {
    case _: NullPointerException => None
  }
}
Use the SafeOption like this, not much different from creating a normal Option:
SafeOption(user.getAddress().getStreet())
Note: use this only in case when you don't care about the null's and a None is a valid option for you in those cases.

Another note: It would be possible for SafeOption to catch any kind of Exception or Throwable instead of only a NullPointerException, but this would totally depend on you application whether that is a valid solution or not. I just choose to only catch NullPointerException so other kinds of exceptions can still be handled differently by the application.

Happy Optioning ;-)

Wednesday, July 30, 2014

Running Jetty as an application for fast starts and easy debugging

Here a simple utility that will safe you a lot of time doing restart or redeployments of your webapp in Jetty. It also makes debugging a lot easier. And the integration of tools like JRebel is now a real breeze.
Before I used the Jetty Maven plugin, but that always recompiled all code and since I have mixed in Scala with Java code, compiling has not become any faster.

Here is the code of a simple App which embeds Jetty and allows you run or debug your webapp from any IDE. The code is in Scala (of course :-)), but is easy translatable to Java.

import org.eclipse.jetty.server.Server
import org.eclipse.jetty.webapp.WebAppContext

/**
 * App to run Jetty for testing.
 */
object JettyApp extends App {

  val server = new Server(8080)

  Runtime.getRuntime.addShutdownHook(new Thread(new Runnable {
    override def run(): Unit = server.stop
  }))

  val context = new WebAppContext()
  context.setDescriptor(context + "/WEB-INF/web.xml")
  context.setResourceBase("src/main/webapp")
  context.setContextPath("/")
  context.setParentLoaderPriority(true)

  server.setHandler(context)

  server.start()
  server.join()
}


Put this in your src/test/[scala|java] folder and the server will use the resources and classes from both the main and test locations.

The only dependency you need to add to you project is org.eclipse.jetty:jetty-webapp:9.2.2.v20140723:test.

The shutdown hook might not be necessary, but I threw it in anyway.

Happy Jetty-ing. ;-)

Thursday, July 10, 2014

Java8 fix for jaxws-maven-plugin

Today I can across an issue while trying to move a project to Java 8. The jaxws-maven-plugin we use to generate code from WSDL files. With Java8 this plugin caused this issue:
Exception in thread "main" java.lang.ClassCastException: java.lang.AssertionError cannot be cast to java.lang.Exception
  at org.jvnet.jax_ws_commons.jaxws.Invoker.main(Invoker.java:87)

This was a known issue already, but not fixed by anyone yet. So I decided to fix it myself.
The fix was rather easy: not case the exception anymore and update the maven-plugin-plugin dependency.

Then in our project, besides using the custom build jaxws-maven-plugin, I also had to update the jaxws-rt dependency to the latest version (2.2.10-b140319.1121) because an older version caused a NPE in AbstractJaxwsMojo.isArgSupported(..). I tried to remove this dependency completely because the JDK also has contains javax.xml.ws packages, but the AbstractJaxwsMojo does not support that (yet).

Since the jaxws-maven-plugin is still in a Subversion repo, I created a new Git repo with my fix which is available at https://bitbucket.org/diversit/jaxws-maven-plugin.

References:
Jaxws-common project home : https://jax-ws-commons.java.net/
Issue JAX_WS_COMMONS-129 : https://java.net/jira/browse/JAX_WS_COMMONS-129
Jaxwx-commons source code : https://java.net/projects/jax-ws-commons/sources/svn/show

Friday, June 6, 2014

Loading dynamic Angular content via JQuery

Sometimes you cannot start a project from scratch. Sometimes you're just stuck with crap created by others. And often you want to improve that.

Say, you're stuck with a web application full with JQuery (created in some not to be named country in South Asia starting with 'I' and ending with 'ndia') and you are really trying to make something better of it. You don't understand anything of this Indian JQuery magic, so you gradually replace it with some clear, tested! and short Angular code.

You created a nice Angular component, added it to your application, but somehow it works in one page but not on another. After some debugging you notice that when the component doesn't work, it is in some html fragment which is dynamically loaded using 'ajaxSubmit' function from JQuery's Form plugin. This dynamic loading is outside of Angular's scope, so Angular does not know this is happening and therefore cannot do any Angular stuff on the new fragment.

The trick to solve this, is to 'compile' the new html fragment using Angular and then insert it into the DOM. This gives Angular the opportunity to activate any Angular components in the fragment. Now, the big question is, how to do this 'compiling' ? Let's go through it step by step.

Before

This was how it was before
$(this).ajaxSubmit({target:'#body',url:'/my/mvc/url'});
This replaced the content of the html tag with id 'body' (so not the contents '<body>' tag itself!) with the html returned by the url '/my/mvc/url'.

Calling an Angular function from plain JavaScript

Somehow the returned html fragment must be compiled, so we need a function which call's Angular's compiler and pass the new html. But, JQuery cannot access Angular's providers or services, so the function must be in Angular. For JQuery to be able to access the function, you must put it somewhere where JQuery can reach it. At first I put the function on Angular's $rootScope like this:
app.run(function($rootScope) {

    $rootScope.refresh = function() {
        console.log('refreshing body');
    }
});
You can then reach this function by getting the rootScope like this:
var rootScope = angular.element(document).scope();
rootScope.refresh();
You can even get the scope of an element by adding a find('') before the 'scope()':
var elementScope = angular.element(document).find('elemId').scope();
elementScope.refresh();
This also works because an Angular Scope inherit from it's parent Scope. The 'app.run' function is called when the page is loaded so it creates the function on the object at that time.

I did not like this solution, because you have to get the scope first before you're able to call the wanted function. So, I opted for another solution to put the function on the Window object so the function would be globally available. In Angular you can just add the $window argument to a function and then create a new function on that object which can then be called from anywhere in JavaScript.
app.run(function($window) {

    $window.refresh = function() {
        console.log('refreshing body');
    }
});

Compile the new html fragment

Angular has a $compile provider with which you can compile the html fragment.
Using it is as easy as adding the '$compile' argument to the run function. The html can be passed as an argument and the return value is the compiled html which you can then put into the dom.

Adding it to the dom

Somehow adding the html to the dom correctly wasn't very straight forward. An element supports both a 'replaceWith' and a 'html' method to modify is contents, but using:
elem.replaceWith( $compile( newHtml )(elemScope))
displayed the html wrong.
elem.html( $compile( newHtml )(elemScope))
This did not work at all.
Finally:
$(target)['html']( $compile( newHtml )(targetScope));
this seemed to work fine.
For me, it all looked like the same code, just written differently, but apparently it makes a difference.

Calling compile function from ajaxSubmit

Initially, the 'ajaxSubmit' call would 1) call the url and 2) replace the content of the provided target with the new html. Because we have to compile the html before it can be injected, a success handler is required to capture the retrieved data. Then it can be compiled and added to the dom.
$(this).ajaxSubmit({
  // no target! Angularfy function will put code into dom.
  url:'&lt;@core.basePath/&gt;my/mvc/url',
  success: function(data) {
    // call the compile function and add compiled html to dom.
  }
});

The full solution

Putting everything together, this is the solution I ended up with. The 'angularfy' function compiles the html and adds it to the provided target.
app.run(function($window, $compile) {

    /*
     * Function to 'Angular-fy' dynamically loaded content
     * by JQuery. This compiles the new html code and injects it
     * into the DOM so Angular 'knows' about the new code.
     */
    $window.angularfy = function(target, newHtml) {
        // must use JQuery to query for element by id.
        // must wrap as angular element otherwise 'scope' function is not defined.
        var targetScope = angular.element($(target)).scope();

//        elem.replaceWith( $compile( newHtml )(elemScope)); Displays html wrong.
//        elem.html( $compile( newHtml )(elemScope)); Does not work.
        $(target)['html']( $compile( newHtml )(targetScope)); // Does work!
        targetScope.$apply();
    }
});
In the web page, the ajaxSubmit calls the 'angularfy' function from the success handler.
$(this).ajaxSubmit({
  // no target! Angularfy function will put code into dom.
  url:'&lt;@core.basePath/&gt;my/mvc/url',
  success: function(data) {
    angularfy('#body', data); // to notify Angular of new html code in dom.
  }
});

Happy Angular-JQuery-ing ! ;-)

Btw: I am a hardcore Java/Scala backender and do not pretend to be a frontend/Angular guru. This solution might not be the nicest one, but for me, at this moment, it works. If you know any improvements, let me know.

Wednesday, May 28, 2014

Java 8's Optional frustrations

At my current project we started working with Java 8 this week. Mainly because of the new Streaming Api so we could do some functional coding in Java and get rid of the Google Guava dependency (which I kind of introduced some weeks ago, because, well, I just hate doing for-loops and null-checks. Once you’ve done Scala you don’t want to go back ;-).
Being used to work with Scala’s Option, I eagerly got started to remove all null-checks and start working with Java’s Optional. The Optional is a nice addition but after working with it for a few days I feel it is dead-wrong in 2 basic and primary methods:

1. To create an Optional, you use Optional.of(..). I threw in a value which could be null and immediately got a NPE. Apparently there is an Optional.ofNullable() method. WTF!! I cannot think of any reason why the ‘of’ method should not accept null’s. Why oh why would you otherwise want to use an Optional if you know the value is never null ! Having to use ‘ofNullable’ is just unnecessary typing and is polluting the code. The ‘of’ method is just useless.

2. Working with requests and contexts, I sometimes want to get one attribute, but, if it’s not set, I want to fall back to another attribute which also might not be set. So, I want to create an Optional and use ‘orElse’ to use another optional value. However, in Java the Optional.orElse returns ’T’ and not an ‘Optional<T>’. In contrast to Scala's Option which ‘orElse’ does return ‘Option[T]’. The ‘Optional.orElse’ method is really a ‘getOrElse’ returning the value of the Optional or an alternative. A real ‘orElse’ function is just missing. I don’t want the value T, I want to keep working with the Optional in a functional way. Now, to get around this you have to do something like this:
Optional.ofNullable(Optional.ofNullable(getValueA()).orElse(getValueB())). How is that for readability? 

Besides these clear mistakes (IMHO) I regret the Optional has not found it’s way into some other classes, like a Map.getOptional method for example, to be able to get Optional instances right away instead of having to do the wrapping yourself.

Friday, April 19, 2013

WebDav4Sbt version 1.2 released

Today version 1.2 of the WebDav4Sbt plugin was released.
This version fixes an issue with publishing Ivy artifacts to WebDav. Thanks to Flanker_9 for raising the issue.

To publish an artifact Ivy-style instead of Maven add to your _build.sbt_:

    publishMavenStyle := false

For more info, see the WebDav repo: https://bitbucket.org/diversit/webdav4sbt.
I got the permission to add my plugin to the plugins list on sbt-scala.org. Although I am very busy at the moment, I'm going to try to do this soon.

Saturday, March 23, 2013

New Webdav4Sbt release adds crossPaths support

Version 1.1 of the Webdav4Sbt plugin was just released.
The new version adds support for publishing Java artifacts which do not need the Scala version in the artifact name. To remove the Scala version from the Java artifact name, add to your build.sbt:

    crossPaths := false

Thanks to jplikesbikes for this contribution.

See the Webdav4Sbt plugin site for more info.