<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tales From The Cloud &#187; java</title>
	<atom:link href="http://blog.newsplore.com/category/software/java-software/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.newsplore.com</link>
	<description>Everything beta</description>
	<lastBuildDate>Tue, 07 Sep 2010 10:40:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>RESTful error handling with Tomcat and SpringMVC 3.x</title>
		<link>http://blog.newsplore.com/2010/08/04/restful-error-handling-with-tomcat-springmvc</link>
		<comments>http://blog.newsplore.com/2010/08/04/restful-error-handling-with-tomcat-springmvc#comments</comments>
		<pubDate>Wed, 04 Aug 2010 09:16:06 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[Java SpringMVC REST Error Handling]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1602</guid>
		<description><![CDATA[Handling errors in a REST way is seemingly simple enough: upon requesting a resource, when an error occurs, a proper status code and a body that contains a parseable message and using the content-type of the request should be returned. The default error pages in Tomcat are ugly. Not only they expose too much of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F08%2F04%2Frestful-error-handling-with-tomcat-springmvc"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F08%2F04%2Frestful-error-handling-with-tomcat-springmvc" height="61" width="51" /></a></div><p>Handling errors in a REST way is seemingly simple enough: upon requesting a resource, when an error occurs, a proper status code and a body that contains a parseable message and using the content-type of the request should be returned.<br />
The default error pages in Tomcat are ugly. Not only they expose too much of the server internals, they are only HTML formatted and making them a poor choice if a RESTful web service is deployed in that Tomcat container. Substituting them to simple static pages is still no enough since I want a dynamic response containing error information.</p>
<p>Here&#8217;s how to do it in 3 simple steps:</p>
<p><span id="more-1602"></span></p>
<p><i>Step 1</i><br />
In web.xml </p>
<pre>
   &lt;servlet&gt;
      &lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/error.jsp&gt;
   &lt;/servlet&gt;
   &lt;!-- other servlet mappings --&amp;gt&amp;

  &lt;error-page&gt;
    &lt;error-code&gt;404&lt;/error-code&gt;
    &lt;location&gt;/error.jsp&lt;/location&gt;
  &lt;/error-page&gt;
  &lt;error-page&gt;
    &lt;error-code&gt;400&lt;/error-code&gt;
    &lt;location&gt;/error.jsp&lt;/location&gt;
  &lt;/error-page&gt;
...
  &lt;error-page&gt;
    &lt;exception-type&gt;java.lang.Throwable&lt;/error-code&gt;
    &lt;location&gt;/error.jsp&lt;/location&gt;
  &lt;/error-page&gt;
</pre>
<p>The servlet called <b>jsp</b> comes out-of the box with the Tomcat container and is the one responsible for processing JSPs . Make sure this mapping comes first, especially if you have a catch-all url-pattern that should map all other URLs to your webapp.</p>
<p><i>Step 2</i><br />
Create a file called errors.jsp in the root of your web application:</p>
<pre>
&lt;%@ page contentType="application/json" pageEncoding="UTF-8"%&gt;
{
   status:&lt;%=request.getAttribute("javax.servlet.error.status_code") %&gt;,
   reason:&lt;%=request.getAttribute("javax.servlet.error.message") %&gt;
}
</pre>
<p><i>Step 3</i><br />
Hook the exception handling using @ExceptionHandler:</p>
<pre>
@Controller
public class SomeController {
...

@ExceptionHandler(BusinessException.class, ValidationException.class, ...)
public void handleApplicationExceptions(Throwable exception, HttpServletResponse response) {
   String formattedErrorForFrontEnd = formatErrMessage(exception);
   if(exception instanceof BusinessException) {
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
formattedErrorForFrontEnd);
   } else if (exception instanceof ValidationException) {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST, formattedErrorForFrontEnd);
   }
   ...
}

//other @ExceptionHandlers skipped

   private String formatErrMessage(Throwable exception) {
      //skipped
   }
}
</pre>
<p>I used @ExceptionHandler to map between application exceptions and error codes. You can apply message formatting as well if the default messages are not sufficient. Also, consider having an @ExceptionHandler(Throwable.class) for the &#8220;all other exceptions&#8221; case.</p>
<p>As you can see, there is no need to write another Spring Controller that handles exceptional paths. The error-page mappings in web.xml, a 2 line JSP and the standard @ExceptionHandler combination was sufficient.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2010/08/04/restful-error-handling-with-tomcat-springmvc" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2010/08/04/restful-error-handling-with-tomcat-springmvc/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Spring 3.0 MVC for RESTful web services (rebuttal)</title>
		<link>http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal</link>
		<comments>http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal#comments</comments>
		<pubDate>Tue, 23 Feb 2010 22:18:53 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SpringMVC]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1486</guid>
		<description><![CDATA[Update Mar.04 Thanks to @ewolff some of the points described below are now official feature requests. One (SPR-6928) is actually scheduled in Spring 3.1 (cool!). I&#8217;ve updated the post and added all open tickets. Please vote! This post is somewhat a response to InfoQ&#8217;s Comparison of Spring MVC and JAX-RS. Recently I have completed a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F02%2F23%2Fspring-mvc-3-0-rest-rebuttal"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F02%2F23%2Fspring-mvc-3-0-rest-rebuttal" height="61" width="51" /></a></div><p><i>Update Mar.04</i> Thanks to @ewolff some of the points described below are now official feature requests. One (<a href='http://jira.springframework.org/browse/SPR-6928'>SPR-6928</a>) is actually scheduled in Spring 3.1 (cool!). I&#8217;ve updated the post and added all open tickets. Please vote!</i></p>
<p>This post is somewhat a response to InfoQ&#8217;s <a href='http://www.infoq.com/articles/springmvc_jsx-rs'>Comparison of Spring MVC and JAX-RS</a>.<br />
Recently I have completed a migration from a JAX-RS implementation of a web service to Spring 3.0 MVC annotation-based <i>@Controllers</i>. The aforementioned post on InfoQ was published a few days after my migration so I&#8217;m dumping below the list of problems I had, along with solutions. </p>
<p>Full list of issues:</p>
<ul>
<li> <a href='#relpaths'>Same relative paths in multiple controllers not supported</a>
<li> <a href='#exchandling'>@ExceptionHandler is controller-centric</a>
<li> <a href='#views'>Standard content negotiation can&#8217;t respond with a fixed response type</a>
<li> <a href='#jsr303'>JSR 303 bean validation not applied in @Controllers</a>
<li> <a href='#respfmt'>Formatting responses (i.e. Date) not working when using Spring formatter annotations</a>
</ul>
<p><a name='relpaths'></a><br />
<b>Same relative paths in multiple @Controllers not supported</b><br />
Consider two Controllers where I use a versioned URL and a web.xml file that uses two URL mappings:</p>
<pre>
@Controller
public class AdminController {
   @RequestMapping("/v1/{userId}")
   public SomeResponse showUserDetails(String userId) {
      ...
   }
}

@Controller
public class UserController {
   @RequestMapping("/v1/{userId}")
   public SomeOtherResponse showUserStreamtring userId) {
      ...
   }
}
In web.xml:
	&lt;servlet-mapping&gt;
	  &lt;servlet-name&gt;public-api&lt;/servlet-name&gt;
	  &lt;url-pattern&gt;/public&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
	&lt;servlet-mapping&gt;
	  &lt;servlet-name&gt;admin-api&lt;/servlet-name&gt;
	  &lt;url-pattern&gt;/admin&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
</pre>
<p><span id="more-1486"></span><br />
Here I want to implement handling for <i>/admin/v1/{userId}</i> as well as <i>/user/v1/{userId}</i>. Each controller serves a different purpose (admin and public) and I want to keep the servlet application contexts separate for each servlet mapping (for instance add authentication and different view resolvers to all /admin/* URLs).<br />
Deploying this configuration barfs the following exception:</p>
<pre>
java.lang.IllegalStateException: Cannot map handler [UserController] to URL path
[/v1/{userId}]: There is already handler [com.test.controller. UserController@6b177115]
mapped.
</pre>
<p>I would like Spring MVC to account for web.xml servlet mappings before deciding that two identical @RequestMappings in different controllers refer to the same URI. My solution was to have all @RequestMappings specifying the full path and resorting to a custom <a href='#views'>view</a> to work around this issue).</p>
<p><a name='exchandling'></a><br />
<b>@ExceptionHandler is controller-centric</b><br />
RESTful web services respond with the usual HTTP responses (200s, 400s, 500s, etc.). These responses are being mapped from application exceptions and it only makes sense to specify the same @ExceptionHandler for all @Controllers since most (if not all) exceptions handled by them are for the same business domain. Currently SpringMVC only supports declaring and @ExceptionHander per controller and not globally per webapp. This forces the implementors to extend their @Controller classes from a common one where the @ExceptionHandler is specified or, to use composition and delegate exception handling to one service which leads to duplication. Both are ugly. There are several ways to deal with exceptions (check <a href='http://jira.springframework.org/browse/SPR-5622?focusedCommentId=43377&amp;page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_43377'>SPR-5622</a>; please guys, add this to the main Spring documentation) but ideally I&#8217;d like to see a global scoped handler like @ExceptionHandler(scope=APPLICATION) where I can remap once framework exceptions to more suitable ones that translate into proper error codes (like working around <a href='http://jira.springframework.org/browse/SPR-5622'>SPR-5622</a> like issues).</p>
<p><a name='views'></a><br />
<b>Standard content negotiation can&#8217;t respond with a fixed response type (<a href='http://jira.springframework.org/browse/SPR-6937'>SPR-6937</a>)</b><br />
Here&#8217;s a simple requirement: Implement an RSS feed that serves a user&#8217;s activity stream.<br />
Here&#8217;s another requirement (make that best practice): </p>
<pre>Service methods should have as arguments primitives, wrappers or other POJOs and
 respond with void, primitives, wrappers or other POJOs.</pre>
<p>I want testability, readability and portability for service classes and using framework objects for arguments/return objects adds unacceptable clutter.<br />
As such, no framework objects are allowed as arguments or return types in a @Controller and in this case I don&#8217;t want to work with <a href='http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/ModelAndView.html'>ModelAndView</a>s just to be able to select the desired View.<br />
Since this new requirement (add RSS view) belongs to the user domain, I want to add a method in the UserController class that returns a POJO which should be always unmarshalled into RSS regardless of request content type (there goes <a href='http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.html'>ContentNegotiationViewResolver</a>). The same controller has other methods returning POJO view objects that I want marshalled into JSON or plain text response body and an HTTP response status. This is already available in RESTEasy via the elegant <a href='http://jboss.org/file-access/default/members/resteasy/freezone/docs/1.0.1.GA/javadocs/javax/ws/rs/Produces.html'>Produces</a> annotation. The same RESTful controller should respond with different response types for different requests since I want to keep its domain centered around the user (and not response types).</p>
<pre>
...
public class UserController {
...
   @RequestHandler("/rss/{userId}")
   public SomePOJO getRssFeed(String userId) {
      ...
      //returns a POJO that should always be resolved by an RSS view
   }

   @RequestMapping("/activity/{userId}")
   public SomeOtherPOJO showUserStream(String userId) {
      ...
      //return POJO that should always be resolved by a JSON view
   }
...
}
</pre>
<p>It turns out this is not immediately possible. To my knowledge none of the included view resolvers provide a straight mapping between URLs and views so I had to write one that configures like this:</p>
<pre>
&lt;bean class="UrlToViewViewResolver"&gt;
   &lt;map name="urlToViewMap"&gt;
      &lt;property key="/user/rss/*" value="rssView"/&gt;
      &lt;property key="/user/activity/*" value="jsonView"/&gt;
      ...
   &lt;/map&gt;
&lt;/bean&gt;
</pre>
<p>The implementation (not included) is trivial and based on <a href='http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/util/AntPathMatcher.html'>AntPathMatcher</a>, a utility class readily available in Spring.</p>
<p><a name='jsr303'></a><br />
<b>JSR 303 bean validation not applied in @Controllers (<a href='http://jira.springframework.org/browse/SPR-6928'>SPR-6928</a>, scheduled for 3.1)</b><br />
On Springsource&#8217;s weblog there&#8217;s a nice tutorial on how to get validation and type conversion in Spring 3.0 <a href='http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/'>here</a>. When it comes to validation though, Spring only supports it &#8220;after binding user input to it&#8221;. It is not possible to validate arguments and return types for a RESTful controller (no web forms or user input of any kind there). This means this won&#8217;t work out of the box:</p>
<pre>
   @RequestHandler("/admin/", method = RequestMethod.PUT )
   public void updateUser(@Valid User user) {
      ...
      //returns a POJO that should always be resolved by an RSS view
   }
</pre>
<p>since in a RESTful scenario the User object won&#8217;t be bound from a form but unmarshalled from XML/JSON/CSV or any other wire format.<br />
To enable validation for a RESTful controller I chose to use @Valid at the method level and add an around advice that intercepts all methods annotated as such then use a <a href='http://java.sun.com/javase/6/docs/api/javax/xml/validation/Validator.html'>Validator</a> to  validate arguments and return objects.</p>
<pre>
&lt;aop:config proxy-target-class="true"&gt;
	&lt;aop:pointcut id="validatableMethodExecution"
        expression="execution(* com.mycorp..*.*(..)) and @annotation(javax.validation.Valid)"/&gt;

	&lt;aop:aspect id="validateArgumentsAndReturnObject" ref="validatorAspect"&gt;
		&lt;aop:around pointcut-ref="validatableMethodExecution" method="validate"/&gt;
	&lt;/aop:aspect&gt;
&lt;/aop:config&gt;

public class ModelValidatorAspect {
	@Autowired
	private Validator validator;

    public Object validate(ProceedingJoinPoint pjp) throws Throwable {
        Set&lt;ConstraintViolation&gt; violations =new HashSet&lt;ConstraintViolation&gt;();
        for(Object obj : pjp.getArgs()) {
            if(obj != null) {
                violations.addAll(validator.validate(obj));
            }
        }
        if(!violations.isEmpty()) {
            throw new BadRequestException(composeErrorMessage(violations));
        }

        Object ret = pjp.proceed();

        //validate return object and throw exception if the validation fails.
        if(ret != null) {
            violations = validator.validate(ret);
        }
        if(!violations.isEmpty()) {
            throw new BusinessValidationException(violationsStr);
        }
   }
}
</pre>
<p>This could get more complex if you have deal with collections of validatable objects but it&#8217;s not hard to enhance the code to handle that.</p>
<p><a name='respfmt'></a><br />
<b>Formatting responses (i.e. Date) not working using Spring formatter annotations</b><br />
Spring comes with some niceties like @DateTimeFormat and @NumberFormat and naturally I want to rely on them by annotating the class attributes of return types used by @Controllers.<br />
That&#8217;s not quite working since the formatters work with form-backed model objects. However, if you use a <a>MappingJacksonJsonView</a> there is a way of formatting using Jackson&#8217;s own <a href='http://jackson.codehaus.org/1.2.1/javadoc/org/codehaus/jackson/map/annotate/JsonSerialize.html'>@JsonSerialize</a>.</p>
<p>Although at times it felt that the switch to SpringMVC was too much, the features that come with it (like abstracting web-related properties as annotations) will turn your RESTful controllers into annotated POJOs focused on the business domain which ultimately means maintainable code.</p>
<p><i>Update Mar.04</i> I left out several points about JSON marshalling that didn&#8217;t work as expected (Jackson marshaller is a handful).<br />
- One enhancement I suggested to ease the pain of configuring JSON marshalling is creating a namespace similar to oxm (<a href='http://jira.springframework.org/browse/SPR-6943'>SPR-6943</a>)<br />
- The second was to add <a href='http://jettison.codehaus.org/'>Jetisson</a> support (<a href='http://jira.springframework.org/browse/SPR-6938'>SPR-6938</a>) as an alternative to Jackson JSON marshaller.</p>
<p>I&#8217;m keen on your feedback regarding these issues so if you have better solutions please comment.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2010/02/23/spring-mvc-3-0-rest-rebuttal/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unit testing with Commons HttpClient library</title>
		<link>http://blog.newsplore.com/2010/02/09/unit-testing-with-httpclient</link>
		<comments>http://blog.newsplore.com/2010/02/09/unit-testing-with-httpclient#comments</comments>
		<pubDate>Wed, 10 Feb 2010 00:31:25 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1442</guid>
		<description><![CDATA[I want to write testable code and occasionally I bump into frameworks that make it challenging to unit test. Ideally I want to inject a service stub into my code then control the stub&#8217;s behavior based on my testing needs. Commons Http Client from Jakarta facilitates integration with HTTP services but how to easily unit [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F02%2F09%2Funit-testing-with-httpclient"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2010%2F02%2F09%2Funit-testing-with-httpclient" height="61" width="51" /></a></div><p>I want to write testable code and occasionally I bump into frameworks that make it challenging to unit test. Ideally I want to inject a service stub into my code then control the stub&#8217;s behavior based on my testing needs.<br />
<a href='http://hc.apache.org/httpclient-3.x/'>Commons Http Client</a> from Jakarta facilitates integration with HTTP services but how to easily <i>unit test</i> code that depends on the HttpClient library? Turns out it&#8217;s not that hard.<br />
I&#8217;ll cover both 1.3 and the newer 1.4 versions of the library since the older v1.3 is still widely used.<br />
Here&#8217;s some typical service (HttpClient v1.3) we want to test. It returns the remote HTML page title:</p>
<pre>
public class RemoteHttpService {
   private HttpClient client;

   public String getPageTitle(String uri)  throws IOException {
     String contentHtml = fetchContent(uri);
     Pattern p = Pattern.compile("&lt;title&gt;(.*)&lt;/title&gt;");
     Matcher m = p.matcher(contentHtml);
     if(m.find()) {
        return m.group(1);
     }
     return null;
   }

   private String fetchContent(String uri)  throws IOException {
      HttpMethod method = new GetMethod("http://blog.newsplore.com/" + uri);
      int responseStatus = client.executeMethod(method);
      if(responseStatus != 200) {
        throw new IllegalStateException("Expected HTTP response status 200 " +
"but instead got [" + responseStatus + "]");
      }
      byte[] responseBody = method.getResponseBody();
      return new String(responseBody, "UTF-8");
   }

   public void setHttpClient(HttpClient client) {
      this.client = client;
   }
}
</pre>
<p>with the HttpClient is injected at runtime (via some IoC container or explicitly).<br />
To be able to unit-test this code we have to come-up with a stubbed version of the HttpClient and emulate the GET method. </p>
<p><span id="more-1442"></span><br />
 What we really want is to be able to control the byte array returned by method.getResponseBody() and although we can inject a mocked HttpClient, the actual class that is responsible for producing the response body is GetMethod which is instantiated (and completely encapsulated) in the method body so we can&#8217;t inject a stubbed GetMethod version directly.<br />
The solution is to create a simple HttpClient mock that is able to control the response status and response body. Here it is:</p>
<pre>
package org.apache.commons.httpclient;

import org.apache.commons.httpclient.*;

public class HttpClientMock extends HttpClient {
   private int expectedResponseStatus;
   private String expectedResponseBody;
   public HttpClientMock (int responseStatus, String responseBody) {
      this.expectedResponseStatus = responseStatus;
      this.expectedResponseBody = responseBody;
   }
   @Override
   public int executeMethod(HttpMethod method) {
      ((HttpMethodBase)method).setResponseStream(
new ByteArrayInputStream(expectedResponseBody.getBytes("UTF-8")));
      return expectedResponseStatus;
   }
}
</pre>
<p>There are two things to notice: Firstly, I placed HttpClientMock in the org.apache.commons.httpclient package to be able to have access to the protected member HttpMethodBase:setResponseStream. Secondly, I downcasted HttpMethod to HttpMethodBase to get access to setResponseStream (it&#8217;s safe since all concrete HttpMethods (GetMethod, PostMethod, etc) inherit from it).</p>
<p>Now I can unit test RemoteHttpService like this:</p>
<pre>
public class RemoteHttpServiceTest {
   private RemoteHttpService remoteHttpService = new RemoteHttpService();

   @Test
   public void extractTitleResponseOK()  throws IOException {
      String pageTitle = "A Title";
      String responseBody = "&lt;title&gt;" + pageTitle + "&lt;/title&gt;";
      HttpClientMock mockHttpClient = new HttpClientMock(200, responseBody);
      remoteHttpService.setHttpClient(mockHttpClient);
      String resultedPageTitle = remoteHttpService.getPageTitle(""); //home page
      Assert.assertTrue(pageTitle.equals(resultedPageTitle));
   }
}
</pre>
<p>I can also add a negative test:</p>
<pre>
   @Test(expected = IllegalStateException.class)
   public void respondsWithInternalServerError()  throws IOException {
      HttpClientMock mockHttpClient = new HttpClientMock(500, "");
      remoteHttpService.setHttpClient(mockHttpClient);
      remoteHttpService.getPageTitle("");
   }
</pre>
<p>For HttpClient version 4.x here&#8217;s the refactored service code :</p>
<pre>
   private String fetchContent(String uri) {
        HttpGet httpget = new HttpGet("http://blog.newsplore.com/" + uri);
        HttpResponse response = client.execute(httpget);
        int responseStatus = response.getStatusLine().getStatusCode();
        if(responseStatus != 200) {
           throw new IllegalStateException("Expected HTTP response status 200 " +
"but instead got [" + responseStatus + "]");
        }
        InputStream responseStream = response.getEntity().getContent();
        byte[] responseBytes = IOUtils.toByteArray(responseStream);
        return new String(responseBytes, "UTF-8");
   }
</pre>
<p>Turns out that implementing a HttpClient mock by extending the DefaultHttpClient (the provided implementation of HttpClient) is not easy. The method I want to override is <i>public HttpResponse execute(HttpUriRequest request) </i> which is marked &#8216;final&#8217; and the code in DefaultHttpClient looks just too complex to inject stubbed behavior.<br />
What we actually want is to be able to control the return of the aforementioned &#8216;execute&#8217; method since it encapsulates the response status and body (better encapsulation than HttpClient 1.3 if you noticed).<br />
Luckily in this case we can use a readily available mocking framework, Mockito that can stub this entire method and return an HttpResponse that we instantiate with the needed status and response body. Here&#8217;s how to rewrite the tests using it:</p>
<pre>
@Test
public void extractTitleResponseOK() throws IOException {
	String pageTitle = "A Title";
	String responseBody = "";
	HttpResponse response = prepareResponse(200, responseBody);
	HttpClient mockHttpClient = Mockito.mock(HttpClient.class);
	Mockito.when(mockHttpClient.execute(Mockito.any(HttpUriRequest.class)))
			.thenReturn(response);

	remoteHttpService.setHttpClient(mockHttpClient);
	String resultedPageTitle = remoteHttpService.getPageTitle(""); // home page
	Assert.assertTrue(pageTitle.equals(resultedPageTitle));
}

@Test(expected = IllegalStateException.class)
public void respondsWithInternalServerError() throws IOException {
	HttpClient mockHttpClient = Mockito.mock(HttpClient.class);
	HttpResponse response = prepareResponse(500, "");
	Mockito.when(mockHttpClient.execute(Mockito.any(HttpUriRequest.class)))
			.thenReturn(response);
	remoteHttpService.setHttpClient(mockHttpClient);
	remoteHttpService.getPageTitle("");
}

private HttpResponse prepareResponse(int expectedResponseStatus,
               String expectedResponseBody) {
      HttpResponse response = new BasicHttpResponse(new BasicStatusLine(
    		  new ProtocolVersion("HTTP", 1, 1), expectedResponseStatus, ""));
      response.setStatusCode(expectedResponseStatus);
      try {
		response.setEntity(new StringEntity(expectedResponseBody));
	} catch (UnsupportedEncodingException e) {
		throw new IllegalArgumentException(e);
	}
	return response;
}
</pre>
<p>The meat of the above code is</p>
<pre>
HttpClient mockHttpClient = Mockito.mock(HttpClient.class);
HttpResponse response = prepareResponse(...);
Mockito.when(mockHttpClient.execute(Mockito.any(HttpUriRequest.class)))
	.thenReturn(response);
</pre>
<p>that instructs the mocked HttpClient to return a HttpResponse that is instantiated in the test context (seeded if you like) when &#8216;execute&#8217; is called (check Mockito documentation for more details on the syntax).</p>
<p>That&#8217;s it. Happy testing.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2010/02/09/unit-testing-with-httpclient" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2010/02/09/unit-testing-with-httpclient/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New Spincloud feature: heat map overlay</title>
		<link>http://blog.newsplore.com/2009/07/07/new-spincloud-feature-heat-map-overlay</link>
		<comments>http://blog.newsplore.com/2009/07/07/new-spincloud-feature-heat-map-overlay#comments</comments>
		<pubDate>Wed, 08 Jul 2009 00:40:56 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[mashups]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1340</guid>
		<description><![CDATA[&#160;&#160; It took a while since the previous feature update to Spincloud. I have done a number of upgrades to the underlying tech and some intensive code refactoring but nothing visible. The time has come for another eye candy: heat maps. It is a map overlay that shows a color-translated temperature layer based on interpolated [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F07%2F07%2Fnew-spincloud-feature-heat-map-overlay"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F07%2F07%2Fnew-spincloud-feature-heat-map-overlay" height="61" width="51" /></a></div><table>
<tr>
<td><img src="http://blog.newsplore.com/wp-content/uploads/2009/07/heatmap-overlay.jpg" alt="heatmap-overlay" width="319" height="222" class="alignnone size-full wp-image-1343" /></td>
<td>&nbsp;&nbsp;</td>
<td align='justify'>It took a <a href='http://blog.newsplore.com/?p=382'>while</a> since the previous feature update to <a href='http://spincloud.com'>Spincloud</a>. I have done a number of upgrades to the underlying tech and some intensive code refactoring but nothing visible. The time has come for another eye candy: heat maps. It is a map overlay that shows a color-translated temperature layer based on interpolated values of the current weather conditions. It gives a quick indication of the average temperature across all land masses where data is available.</td>
</tr>
</table>
<p> Naturally in areas where data is more dense, the visual representation is better. The toughest job was to figure-out the interpolation math. I still have to refine the algorithm currently based on the <a href='http://en.wikipedia.org/wiki/Inverse_distance_weighting'>inverse distance weighting</a> algorithm which interpolates scattered points on a surface. Apparently a better one to use is <a href='http://en.wikipedia.org/wiki/Kriging'>kriging</a> but I have yet to implement it.<br />
The temperature map is generated from current temperatures and is updated once every hour. You can toggle the overlay by clicking the &#8220;Temp&#8221; button found on the top of the active map area.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/07/07/new-spincloud-feature-heat-map-overlay" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/07/07/new-spincloud-feature-heat-map-overlay/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reviewing Google AppEngine for Java (Part 2)</title>
		<link>http://blog.newsplore.com/2009/06/06/reviewing-google-appengine-for-java-part-2</link>
		<comments>http://blog.newsplore.com/2009/06/06/reviewing-google-appengine-for-java-part-2#comments</comments>
		<pubDate>Sun, 07 Jun 2009 01:18:42 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[BigTable]]></category>
		<category><![CDATA[cloud computing]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1205</guid>
		<description><![CDATA[In the first part I&#8217;ve left-off with some good news: successful deployment in the local GAE container. In this second part I&#8217;ll talk about the following: - Loading data and browsing - Table indexing - Limitations of datastore queries - More datastore limitations and JPA issues - Deployment - Performance - Production monitoring - Usage [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F06%2Freviewing-google-appengine-for-java-part-2"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F06%2Freviewing-google-appengine-for-java-part-2" height="61" width="51" /></a></div><p>In the <a href="http://blog.newsplore.com/?p=1093">first part</a> I&#8217;ve left-off with some good news: successful deployment in the local GAE container. In this second part I&#8217;ll talk about the following:</p>
<ul>
<li>- <a href='#loading'>Loading data and browsing</a></li>
<li>- <a href='#indexing'>Table indexing</a></li>
<li>- <a href='#limqueries'>Limitations of datastore queries</a></li>
<li>- <a href='#dsjpalim'>More datastore limitations and JPA issues</a></li>
<li>- <a href='#deploy'>Deployment</a></li>
<li>- <a href='#perf'>Performance</a></li>
<li>- <a href='#prod'>Production monitoring</a></li>
<li>- <a href='#quotas'>Usage and quotas</a></li>
<li>- <a href='#otherlim'>Other limitations</a></li>
<li>- <a href='#conclusion'>Final thoughts</a></li>
</ul>
<p><a name='loading'></a><br />
<b>Loading data and browsing</b><br />
After finishing-off the first successful deployment, next on the agenda was testing out the persistence tier but for this I needed some data to work with in the GAE datastore.<br />
Along with the local container Google makes available a local datastore but so far the only way to populate the datastore is <a href="http://code.google.com/appengine/docs/python/tools/uploadingdata.html">described here</a> and it uses python. Furthermore, currently there is one documented way to browse the local datastore using the <a href="http://code.google.com/appengine/docs/python/tools/devserver.html#The_Development_Console">local development console</a> but this again requires the python environment. There&#8217;s a <a href="http://groups.google.com/group/google-appengine-java/browse_thread/thread/1684a0871b4a7f21/52c6233da56dfbbd?lnk=raot">hint from Google</a> though that there will be a data viewer for the Java SDK. In the mean time I voted up the <a href="http://code.google.com/p/googleappengine/issues/detail?id=1217&amp;q=datastore%20viewer%20java&amp;colspec=ID%20Type%20Status%20Priority%20Stars%20Owner%20Summary%20Log%20Component">feature request</a>.</p>
<p>Back to bulk loading, after voting on the <a>feature request</a> to have a bulk uploader, I decided not to use the python solution but to handcraft a loader that will fill-in two tables: COUNTRY and COUNTRY_STATE (for federated countries like US and CAN). Since there&#8217;s no way to schedule worker threads (but <a href="http://www.techcrunch.com/2009/05/27/live-from-google-io-2009/">is on it&#8217;s way</a>) the only mechanism to trigger the data loading is via URLs. I&#8217;m using Spring 3.0 and so it wasn&#8217;t hard to create a new @Controller, some methods to handle data loading then map them to URLs:</p>
<pre>@Controller
public class BulkLoadController {
	@RequestMapping("/importCountries")
	public ModelAndView importCountries() {
           ...
        }
	@RequestMapping("/importProvinces")
	public ModelAndView importProvinces() {
           ...
        }
}</pre>
<p><span id="more-1205"></span>Since my SQL script that creates and loads the COUNTRY table is no good (Google&#8217;s BigTable is not RDBMS) I chose to translate all INSERT operations to CSV.</p>
<pre>Before
INSERT INTO COUNTRY (NAME, TWO_L_CODE, THREE_L_CODE, CODE, TIMEZONE)
  VALUES("Antarctica","AQ","ATA",10,12);

After
Antarctica,AQ,ATA,10,12</pre>
<p>You don&#8217;t need to create the table, the GAE container runtime takes care of that both locally and in the hosted environment.<br />
Once I created the CSV file (I named it countries.txt), I made it available to the webapp by placing it in the root of the war folder as the container has support for reading files from the application folders. So the country importer method will look like this (exception handling removed for brevity):</p>
<pre>@RequestMapping("/importCountries")
public ModelAndView importCountries() {
	FileInputStream countriesF = new FileInputStream("countries.txt");
	BufferedReader br = new BufferedReader(new InputStreamReader(countriesF));
	String line = null;
	while((line = br.readLine()) != null) {
		persistCountry(line);
	}
        return new ModelAndView("success");
}</pre>
<p>The only thing I had to do was to implement <span>persistCountry</span> which I did by simply adding a new method on the DAO that would persist a Country entity and injecting the DAO in BulkLoadController. I fired the URL request and I got the OK page back. Since I couldn&#8217;t browse the datastore I resorted to looking in the local_db. file located in WEB-INF/appengine-generated folder and I could see the country names.<br />
<em>Handling Transactions</em><br />
One notable mention regarding transactions is that <em>you can&#8217;t save multiple objects in a single transaction if they are all root entities</em> (see <a href="http://groups.google.com/group/google-appengine-java/browse_thread/thread/04f35b443c15d531?pli=1">comment</a>). I bumped into this while sorting the following exception:</p>
<pre>Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found
 both Element {
  type: "stations"
  id: 500
}
 and Element {
  type: "stations"
  id: 599
}</pre>
<p>To relief the database from unneeded burden, I&#8217;d batch multiple entity updates then issue a single transaction commit. With GAE&#8217;s datastore this is not possible so I had to open and commit transactions for every entity update. This resulted in notably high CPU usage both locally and on the hosted environment but I couldn&#8217;t find any better way of handling this. In my case I had to remove any batching logic from my respective classes and annotate the methods responsible with insert/updates (like persistCountry&#8217;) with @org.springframework.transaction.annotation.Transactional like in the &#8216;persistCountry&#8217; method above or use <a href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html#transaction-programmatic">programmatic transaction management</a> for uploading weather stations as we&#8217;ll see immediately.</p>
<p>There are two more tables I still had to bulk-provision: PROVINCE and STATION but the pattern should the same. So it seemed.<br />
When I tried to provision the PROVINCE table I got no errors but no rows in the database either. My class looks like this:</p>
<pre>@Entity
public class Province implements Serializable {

  private ProvincePK countryCodePK;
  private String provinceName;
  private float timeZone;

  @EmbeddedId
  public ProvincePK getProvincePK() {
    return provincePK;
  }
...

@Embeddable
public class ProvincePK implements Serializable {

  private String stateCode;
  private String countryCode;
...</pre>
<p>From the <a href="http://code.google.com/appengine/docs/java/datastore/creatinggettinganddeletingdata.html#Keys">documentation</a> [via <a href="http://groups.google.com/group/google-appengine-java/browse_thread/thread/5e16a9c0ceb6ec7d/fb3ad9aa6387c084?lnk=raot">groups</a>] I learned that the composite PKs are not supported. However it would have been useful to indicate this either in the enhancement step (still hate it) or deployment. So issue <a href="http://code.google.com/p/googleappengine/issues/detail?id=1658">1658</a> was born. Vote it if you want it implemented.<br />
The solution is not easy in most cases but I reverted to a single field PK in the Province entity since it was possible in my case. I had the provinces imported after this fix.<br />
Now the harder part. I am using ASCII resources from the internet to import weather stations; In all there are about 20000 stations imported from several resources, both HTTP and FTP. The first thing I learned was that the AppEngine has a request timeout of 30 seconds. I learned this the hard way after trying to perform the same import I&#8217;m using in Spincloud only I was using a URL request to trigger it (I&#8217;m normally using JMX but it&#8217;s not supported by the hosted AppEngine). The error I bumped into was:</p>
<pre>com.google.apphosting.runtime.HardDeadlineExceededError: This request (8c8ca701dccad394)
 started at 2009/06/05 07:30:05.088 UTC and was still executing at 2009/06/05 07:30:33.944 UTC.</pre>
<p>Notice the timeline, there is an automatic timeout enforced by the hosted runtime.<br />
Since we can&#8217;t use long running tasks, the alternative is to chain requests that will incrementally add batches of items into the database and we&#8217;ll use a request parameter to control batch increments.</p>
<pre>	@RequestMapping("/updateWeatherStations")
	public ModelAndView updateWeatherStations(HttpServletRequest request) {
		int position = Integer.parseInt(request.getParameter("position"));
		wmoStationsImporter.saveWeatherStations(position);
	}</pre>
<p>The method saveWeatherStations will save a set of items into the datastore; the &#8216;position&#8217; parameter indicates the start index of the item list; the batch size is constant and so with each request the &#8216;position&#8217; parameter will have to increment with the batch size.</p>
<pre>private static final int BATCH_SIZE = 50;
public void fetchWMOData(int position) {
	int recordNo = 0;
	int startIndex = position * BATCH_SIZE;
	String nextLine = null;
	BufferedReader isr = new BufferedReader(new InputStreamReader(getStationsFileInputStream()));
	String nextLine = null;
	while ((nextLine = isr.readLine()) != null) {
		recordNo++;
		if (recordNo  startIndex + BATCH_SIZE) {
			logger.info("Finished batch");
			return;
		}
		//parse record and save weather station
	}
}</pre>
<p>Some observations with the above code: first, I&#8217;m reading a local ASCII file that contains stations I want to save into the datastore. Secondly I found a reasonable value for the BATCH_SIZE; the higher the number, the more time the processing takes (reading from file, parsing record and saving entity into the datastore) and you may hit again the 30 seconds limit. I&#8217;m also using local files to load the ASCII data since the request limit is so tight and I don&#8217;t want to wait for resources to be downloaded off the internet for most part.</p>
<p>What&#8217;s left is to &#8220;weld&#8221; requests together using a shell script. The number of requests is the total number of records divided by BATCH_SIZE.</p>
<pre>#/bin/sh
count=25
while [ "$count" -le 133 ]
do
  wget "http:///updateStations?position=$count"
  let "count += 1"
  sleep 8
done</pre>
<p>To play nicely with the hosted environment and not to get throttled, I&#8217;m pausing 8 seconds after each request.<br />
In conclusion I really need a better way to handle bulk loading. Best is to be able to use SQL data dumps to load the datastore.</p>
<p><a name='indexing'></a><br />
<b>Table indexing</b><br />
The datastore indexes each column so you don&#8217;t need to do it explicitly. However, for all JPA queries that use more than one field in the criteria, composite field indexing is needed. The local environment will create an datastore index config file for you  (WEB-INF/datastore-indexes.xml) and moreover, it will create the indexing configuration but only after actually executing a query at runtime. This is not optimal and I&#8217;d like to see a way to auto-generate the indexes by processing JPA queries (as part of the enhance step maybe?). More about the GAE&#8217;s datastore indexing <a href="http://code.google.com/appengine/articles/index_building.html">here</a><br />
Spatial indexing is not supported.</p>
<p><a name='limqueries'></a><br />
<b>Limitations of datastore queries </b><br />
If you&#8217;re thinking of a straight migration of all existing JPA queries to the datastore be warned. GAE is using a datastore based on the <a href="http://labs.google.com/papers/bigtable.html">BigTable</a> storage system. BigTable follows a different philosophy than traditional RDBMS and so it doesn&#8217;t support many of the standard relational aspects of a database. Here are the documented <a href="http://code.google.com/appengine/docs/java/datastore/queriesandindexes.html">limitations</a>.I have found that queries that use UPPER and LIKE are not supported either.</p>
<pre>org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreFeatureException:
Problem with query : Unsupported method &lt;upper&gt; while parsing expression: InvokeExpression {[null].upper(PrimaryExpression {station, usState})}

org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreOperatorException:
Problem with query &lt;SELECT station FROM com.newsplore.weather.bo.Station station WHERE
 UPPER(station.name) LIKE :stationName ORDER BY station.name&gt;:
App Engine datastore does not support operator  LIKE</pre>
<p>I can live without the UPPER but  queries using LIKE are a must and I was quite surprised to find that they are not supported (TODO: study the BigMap <img src='http://blog.newsplore.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . I have yet to find a replacement for LIKE&#8230;<br />
Plain SQL is also unsupported (not a relational datastore&#8230;). As well, spatial extensions -if supported- are not documented. I&#8217;m using several spatial SQL queries in Spincloud, mostly to <a href="http://blog.newsplore.com/?p=1031">select data</a> from a geographic area.</p>
<p><a name='dsjpalim'></a><br />
<b>More datastore limitations and JPA issues</b><br />
- Primary keys cannot be int types, I had to switch a bunch to Long.<br />
- JPA queries need fully qualified class names; only &#8220;select s from com.package.Station s&#8221; will work.<br />
- Inconsistent NullPointerException when accessing some entities the first time:</p>
<pre>
ERROR MainHandlerExceptionResolver:18  Exception processing page: Name is null
java.lang.NullPointerException: Name is null
	at java.lang.Enum.valueOf(Enum.java:195)
	at com.google.appengine.api.datastore.dev.CompositeIndexManager$IndexSource.valueOf(CompositeIndexManager.java:64)
</pre>
<p>After repeating the request the entities are fetched OK.<br />
- No composite PKs allowed.<br />
- java.sql.TImestamp not supported. The following exception is thrown when accessing an entity containing such type:</p>
<pre>
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: java.sql.Timestamp is not a support
ed property type.; nested exception is java.lang.IllegalArgumentException: java.sql.Timestamp is not a supported prop
erty type.]
</pre>
<p>I had to change all java.sql.Timestamp fields to java.util.Date. I&#8217;m a bit baffled about this one since Timestamp is a subtype of Date. I also changed the @Temporal annotations to TemporalType.DATE.<br />
- No support for uniqueness constraints. I removed all &#8220;unique=true&#8221; clauses in @Column(name=&#8221;SOME_COLUMN&#8221;, unique=true)<br />
- I couldn&#8217;t make @ManyToOne relationships work. I have such relationship for instance between Station (many) and Province (one). Within the transaction that persists a Station, a Province is associated with a Station so first the Province is loaded from the datastore by PK then set it into the new Station object. The error is:</p>
<pre>
Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found both Element {
  type: "PROVINCE"
  name: "NO"
}
 and Element {
  type: "stations"
  id: 21
}
</pre>
<p>This is the same type of constraint that prevents working on multiple root entities within the same transaction.<br />
- Not equals and IN operators are not supported<br />
- I&#8217;m using method-level annotations for entities and I noticed that both the attribute and the getter/setter have to follow the JavaBean rules. With all other JPA providers I can have an arbitrary named field as long as accessors follow JavaBean rules.</p>
<p><a name='deploy'></a><br />
<b>Deployment</b><br />
You can use the neat Eclipse plugin to push the webapp to the hosted GAE or use an included utility called appcfg.sh, your choice. One important limitation is that the total number of files that are allowed to be uploaded is 1000. This issue was solved in the Python environment with the introduction of the <a href="http://googleappengine.blogspot.com/2008/09/sdk-113-now-available-for-download.html">zipserve</a> module but there&#8217;s no equivalent on the Java side yet. In the mean time, one way around it is to deploy a second webapp containing only static files and update the web pages accordingly (or use a real CDN).</p>
<p><a name='perf'></a><br />
<b>Performance</b><br />
Static pages perform quite well. Querying the datastore with indexed data ididn&#8217;t strike me as blinking fast. I can pull for instance 200 weather stations from the datastore (through JPA) and render the results on a JSP web page but if I bump the number of records to 1000 I bump into another limitation of the AppEngine which is a limit on the datastore request:</p>
<pre>ERROR MainHandlerExceptionResolver:18  Exception processing page: datastore timeout:
operation took too long.
com.google.appengine.api.datastore.DatastoreTimeoutException: datastore timeout: operation took too long.
	at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:37)
	at com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall(DatastoreApiHelper.java:55)
...</pre>
<p>According to my non-scientific measurement the datastore timeout is around 5 seconds. A query that returns 1000 records would exceed this deadline. Arguably one shouldn&#8217;t issue queries that return such a high number of records but it&#8217;s better to be aware of this constraint.<br />
I have also experienced an OutOfMemoryException on the hosted environment and I couldn&#8217;t find any facility to redeploy or somehow reset the runtime from the browser&#8217;s admin interface.</p>
<p><a name='prod'></a><br />
<b>Production monitoring</b><br />
Google provides an online web console to monitor the usage, check logs, check quotas and browse the live datastore. I found it useful but a bit more work is needed on the datastore browser to support GUI-oriented querying.</p>
<p><a name='quotas'></a><br />
<b>Usage and quotas</b><br />
Google <a href="http://code.google.com/appengine/docs/quotas.html">offers</a> free usage up to a limit, afterwards there&#8217;s a paid scheme. The usage is free for up to 5 million page views per month which seems quite reasonable.</p>
<p><a name='otherlim'></a><br />
<b>Other limitations</b><br />
A list of what&#8217;s runnable in the AppEngine is found <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">here</a> Of all, I&#8217;ll focus on just one: saving files on the hosted file system is forbidden. I happen to save lots of image tiles for the radar layer so I&#8217;ll be forced to use the BigTable to store the image tiles, not necessarily a bad thing as it forces me to learn more about BigTable. On the other hand I have to point out that this limitation adds to the challenges of migrating to the AppEngine cloud.</p>
<p><a name='conclusion'></a><br />
<b>Final thoughts</b><br />
It&#8217;s quite clear that Google had an aggressive timeline for releasing GAE for Java. GAE(J) is still incomplete and there are some glaring omissions that should be corrected sooner rather than later:<br />
- datastore backup, browser and bulk uploader tool<br />
- spatial extensions support in the datastore. This is a must since given the opportunity for integration with Google Maps.<br />
- background processing (coming soon)<br />
- extending queries to support the LIKE operator or an alternative<br />
- better JPA support. I mean better error messages and better documentation with unsupported features, proper Level 2 cache integration with memcache.<br />
The roadmap is laid-out <a href="http://code.google.com/appengine/docs/roadmap.html">here</a></p>
<p>In conclusion, moving an existing project to Google&#8217;s infrastructure is not a trivial job. The differences between a traditional database and BigMap concepts are at times irreconcilable and code refactoring may prove to be too big a task. I happen to agree with Mr.  Cranrell&#8217;s <a href="http://gigaom.com/2009/06/06/you-say-you-want-a-cloud-revolution/">remarks</a> regarding the challenges with regards to migrating to a non-relational datastore (perfect timing, the article was posted just today) but at the same time I have to appreciate the (revolutionary?) efforts from Google (BigMap) and Amazon (SimpleDB)  to shift the market focus from RDBMS to perhaps better alternatives.</p>
<p>The AppEngine for Java is a worthy player in the new cloud services industry that is shaping as we speak. It is especially relevant for greenfield projects that don&#8217;t come with the standard baggage of constraints (most notably the relational database mapping) and where new and innovative ways of architecting an application can be explored.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/06/06/reviewing-google-appengine-for-java-part-2" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/06/06/reviewing-google-appengine-for-java-part-2/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Upgrading to Spring 3.0.0.M3 and Spring Security 3.0.0.M1</title>
		<link>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1</link>
		<comments>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1#comments</comments>
		<pubDate>Fri, 05 Jun 2009 02:50:31 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Spring Security]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1224</guid>
		<description><![CDATA[A short two months back I posted an article describing how to upgrade to Spring 3.0 M2. Spring folks are releasing at breakneck speed and so I got busy again upgrading spincloud.com to Spring 3.0 M3 released at the beginning of May. Just yesterday (June 3rd) the team released Spring Security 3.0 M1 and I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F04%2Fupgrading-to-spring-300m3-and-spring-security-300m1"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F04%2Fupgrading-to-spring-300m3-and-spring-security-300m1" height="61" width="51" /></a></div><p>A short two months back I <a href='http://blog.newsplore.com/?p=773'>posted</a> an article describing how to upgrade to Spring 3.0 M2. Spring folks are releasing at breakneck speed and so I got busy again upgrading <a href='http://spincloud.com'>spincloud.com</a> to <a href='http://blog.springsource.com/2009/05/06/spring-framework-30-m3-released/'>Spring 3.0 M3</a> released at the beginning of May. Just yesterday (June 3rd) the team <a href='http://blog.springsource.com/2009/05/06/spring-framework-30-m3-released/'>released</a> Spring Security 3.0 M1 and I decided to roll this in Spincloud as well.</p>
<p><b>Upgrading Spring Security from 2.0.4 to 3.0.0 M1</b><br />
For Spring Security 3.0.0 M1 I&#8217;m doing a &#8220;soft&#8221; upgrade since I had done my homework when I migrated from Acegi. I won&#8217;t use any of the new 3.0 features, just getting ready to use them. </p>
<p>To digress a bit, Spring Security a technology that is harder to swallow due to its breadth. To simplify the picture, Spring Security (former Acegi) provides three major security concerns to enterprise applications:<br />
- Authorization of method execution (either through standard JSR-250 JEE security annotations or via specific <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-method-security'>annotation-based method security</a>).<br />
- HTTP Request authorization (mapping URLs to accessible roles using Ant style or regexp&#8217;ed paths,  dubbed <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/channel-security.html#channel-security-config'>channel security</a>).<br />
- Website authentication (integrating Single Sign On (SSO) services by supporting major SSO providers, HTTP BASIC authentication, OpenId authentication and other types).<br />
For Spincloud I&#8217;m using OpenId for authentication and Channel Security to secure website pages.<br />
<span id="more-1224"></span><br />
To perform the upgrade you have to first grab the new jars. Here&#8217;s the Maven config:</p>
<pre>
	&lt;repository&gt;
		&lt;id&gt;Springframework milestone&lt;/id&gt;
		&lt;url&gt;http://maven.springframework.org/milestone&lt;/url&gt;
	&lt;/repository&gt;
	&lt;properties&gt;
		&lt;spring.version&gt;3.0.0.M3&lt;/spring.version&gt;
		&lt;spring-security.version&gt;3.0.0.M1&lt;/spring-security.version&gt;
	&lt;/properties&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-core&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-config&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-openid&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-web&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
</pre>
<p>Make sure your build process refers only to these jars.<br />
in 3.0.0 M1, the package structure was changed. Here&#8217;s what I had to do to upgrade the packages:<br />
Before</p>
<pre>
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.openid.OpenIDAuthenticationStatus;
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
</pre>
<p>After:</p>
<pre>
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.openid.OpenIDAuthenticationStatus;
import org.springframework.security.openid.OpenIDAuthenticationToken;
</pre>
<p>The security namespace has <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html'>changed</a> too so I updated my security XML file namespace and I had only to change the packages for standard Spring Security beans defined  to match the new package structure.</p>
<p><b>Upgrading Spring from 3.0.0 M2 to M3</b><br />
This should be easy. First, grab the new jars through Maven by using the same Maven config I described at the beginning of <a href='http://blog.newsplore.com/?p=773'>this post</a> and change the spring.version to 3.0.0.M3. I&#8217;m planning to move more XML configuration to annotations and M3 enables more of that (@Lazy for instance). I&#8217;m still waiting for the scheduling namespace due to appear in this milestone but pushed to RC1 apparently. I&#8217;m craving for some annotation-based timer configuration too&#8230;</p>
<p><b>Build and deployment</b><br />
At first, the build failed on me with the follwing error:</p>
<pre>
java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
	at org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:205)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:125)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:419)
</pre>
<p>This is because M3 (finally) repackages asm. So I deleted the asm libraries I used to fix the M2 issues and added the repackaged Spring asm library:</p>
<pre>
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;org.springframework.asm&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;
</pre>
<p>If you&#8217;re getting this error on container start-up:</p>
<pre>
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/security]
Offending resource: ServletContext resource [/WEB-INF/classes/applicationContext-security.xml]
</pre>
<p>means you have forgotten to add security-config jar (see the Maven config in the Security section). </p>
<p>That&#8217;s all. Done in 3 hours with no problems at all.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Reviewing Google AppEngine for Java (Part 1)</title>
		<link>http://blog.newsplore.com/2009/05/27/reviewing-google-appengine-for-java-part-1</link>
		<comments>http://blog.newsplore.com/2009/05/27/reviewing-google-appengine-for-java-part-1#comments</comments>
		<pubDate>Thu, 28 May 2009 02:08:56 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[cloud deployment]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Java AppEngine]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1093</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160; When Google announced that Java is the second language that the Appengine will support I almost didn&#8217;t believe it given the surge of the new languages and the perception that Java entered legacy but the JVM is a powerful tried-and-true environment and Google saw the potential of using it for what it is bound [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F05%2F27%2Freviewing-google-appengine-for-java-part-1"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F05%2F27%2Freviewing-google-appengine-for-java-part-1" height="61" width="51" /></a></div><table border="0">
<tbody>
<tr>
<td>
<img class="alignnone size-full wp-image-1136" src="http://blog.newsplore.com/wp-content/uploads/2009/05/appengine_lowres.gif" alt="appengine_lowres" width="142" height="109" /></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td>
<div align='justify'>When Google <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html">announced</a> that Java is the second language that the Appengine will support I almost didn&#8217;t believe it given the surge of the new languages and the perception that Java entered legacy but the JVM is a powerful tried-and-true environment and Google saw the potential of using it for what it is bound to</div>
</td>
</tr>
</tbody>
</table>
<p>become: a runtime environment for the new and exciting languages (see JRuby and Grails). The JVM is the new gateway drug in the world of languages.</p>
<p><i>Note:</i> I&#8217;ll break down this review into two posts as it&#8217;s too extensive to cover everything at once. This first part is about initial setup, JPA and some local webapp deployment issues. In the second part I&#8217;ll describe how to load data into the datastore, data indexing, how I reached some of the limitations of the AppEngine and how to get around some of them.</p>
<p>I managed to snatch an evaluation account and last few days I have been playing with it. (as of today Google opened the registrations to all). My goal was (<a href="http://blog.newsplore.com/?p=981">again</a>) simple: to port Spincloud to the AppEngine. The prize: free hosting which amounts to $20/month in my case (see my <a href="http://blog.newsplore.com/?p=880">post</a> about Java hosting providers), some cool monitoring tools that I can access on the web and of course the transparent super-scalability that Google is touting, in case I get techcrunched, slashdotted or whatever (slim chances but still&#8230;).<br />
I am a couple of weeks into the migration effort and I can conclude that the current state of the AppEngine is not quite ready for Spincloud as I&#8217;ll detail below but it comes quite close. The glaring omission was scheduling but Google <a href="http://www.techcrunch.com/2009/05/27/live-from-google-io-2009/">announced today</a> that the AppEngine will support it (awesome!) and I plan to use it from day one.</p>
<p>My stated goal is running Spincloud on AppEngine. Here are the technologies I use in Spincloud:<br />
- Spring 3.0 (details <a href="http://blog.newsplore.com/?p=773">here</a>)<br />
- SpringAOP<br />
- SpringSecurity with OpenId<br />
- Webapp management with JMX (I know, it won&#8217;t fly)<br />
- Job scheduling using Spring&#8217;s Timer Task abstraction (<a>not optimistic</a> about this one either)<br />
- SiteMesh (upgraded to 2.4.2 <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">as indicated</a>)<br />
- Spatial database support including spatial indexing<br />
- JPA 2.0 (back story <a href="http://blog.newsplore.com/?p=981">here</a>)<br />
- Level 2 JPA cache, query cache.<br />
- Native SQL query support including native SQL spatial queries.<br />
- Image processing (spincloud scraps images and processes pixel-level information to get some weather data)<br />
<span id="more-1093"></span><br />
That&#8217;s a lot of stuff but first things first. I recommend creating a new repository branch (I use Subversion) dedicated to the new environment as there may be many things to change and you still want to continue the development unaffected on your mainline.</p>
<p>I downloaded the latest <a href="http://code.google.com/appengine/downloads.html">SDK</a> and exploded it under the tools/ folder. Make sure you install the Eclipse plugin as it&#8217;s pretty useful.</p>
<p>After the initial setup I started-out with the JPA part since this seemed to be the most challenging piece of technology that I had to change. AppEngine uses DataNucleus JPA provider, a poor choice in my opinion since they are a JDO provider turned to JPA (much like KODO/OpenJPA) and so they drag a lot of JDO baggage along. I haven&#8217;t heard of them before and they don&#8217;t seem to be that popular (why not Hibernate or the new RI: EclipseLink? <i>Update:</i> because JPA is RDBMS oriented while JDO is not and the backing store of GAE is BigTable which is not RDBMS). DataNucleus JPA requires a pre-compilation step that does bytecode enhancement which I completely dislike as it&#8217;s archaic (all modern JPA providers don&#8217;t have this anymore) but I had no choice. So I&#8217;ve followed the <a href="http://code.google.com/appengine/docs/java/datastore/usingjpa.html">reference documentation</a>. The only thing not described there is the ant integration.<br />
Here is what I added to my build.xml</p>
<pre>&lt;project name="weather"  default="build"  basedir="."&gt;
...
  &lt;property name="sdk.dir" value="/Users/florin/tools/appengine-java-sdk-1.2.1"/&gt;
  &lt;import file="${sdk.dir}/config/user/ant-macros.xml" /&gt;

  &lt;path id="enhancer.classpath"&gt;
    &lt;pathelement path="${bin.dir}"/&gt;
    &lt;fileset dir="${sdk.dir}/lib"&gt;
      &lt;include name="appengine-tools-api.jar"/&gt;
    &lt;/fileset&gt;
    &lt;fileset dir="${lib.dir}"&gt;
      &lt;include name="gisjts/jts*.jar"/&gt;
      &lt;include name="appengine/appengine-api-1.0-sdk-1.2.1.jar"/&gt;
    &lt;/fileset&gt;
  &lt;/path&gt;

  &lt;target name="enhance" depends="compile"&gt;
    &lt;enhance verbose="true" classpathref="enhancer.classpath"&gt;
      &lt;fileset dir="${bin.dir}"&gt;
        &lt;include name="com/newsplore/weather/bo/*.class"/&gt;
      &lt;/fileset&gt;
    &lt;/enhance&gt;
  &lt;/target&gt;

  &lt;target name="build-appengine" depends="compile, enhance, jar"/&gt;
...
</pre>
<p>Essentially this is to accommodate the enhancement step (notice how the &#8220;enhance&#8221; target is interposed between compile and jar in the build-appengine target).<br />
I ran the &#8220;build-appengine&#8221; target and noticed the first exception:</p>
<pre>  [enhance] Please see the logs [/tmp/enhance64409.log] for further information.</pre>
<p>That&#8217;s a convoluted way of looking at the errors (why not showing the exception in the console?). Here&#8217;s the actual error found in the said file:</p>
<pre>java.lang.RuntimeException: Unexpected exception
...
   Caused by: java.lang.reflect.InvocationTargetException
...
Caused by: java.lang.NoClassDefFoundError: Lorg/apache/log4j/Logger;
  at java.lang.Class.getDeclaredFields0(Native Method)</pre>
<p>This was because one of my business objects used log4j. Adding the log4j jar file didn&#8217;t help and the solution was to remove the logging from the class altogether.</p>
<p>After cleanup I got this error:</p>
<pre>  [enhance] SEVERE: Class "com.newsplore.weather.bo.GeometryUserType" was not found in the
CLASSPATH. Please check your specification and your CLASSPATH.
  [enhance] org.datanucleus.exceptions.ClassNotResolvedException: Class
"com.newsplore.weather.bo.GeometryUserType" was not found in the CLASSPATH.
    Please check your specification and your CLASSPATH.</pre>
<p>That was because GeometryUserType (a class I used to handle Geometry types in Hibernate) was in the com.newsplore.weather.bo package and the enhancer went through all classes in this package thinking they are all @Entities and failed with this one. Weird, I thought that the enhancer was smarter and filtered-out all non @Entities&#8230; The solution is either to specify all the classes to be enhanced in the &#8220;enhance&#8221; ant target or move the non-entities to other packages (a good practice). In my case I deleted the class since I wasn&#8217;t using it anyway (I used this utility class before Hibernate became a JPA provider).<br />
After this cleanup, the enhance target spat yet another error:</p>
<pre>[enhance]Class com.newsplore.weather.bo.UsForecast has property weatherIconByCode declared
    in MetaData, but its getter method doesnt exist in the class!
  [enhance] May 27, 2009 4:03:50 PM org.datanucleus.enhancer.DataNucleusEnhancer main
[enhance] SEVERE: DataNucleus Enhancer completed with an error. Please review the enhancer
log for full details. Some classes may have been enhanced but some caused errors
  [enhance] Class com.newsplore.weather.bo.UsForecast has property weatherIconByCode
declared in MetaData, but its getter method doesnt exist in the class!
  [enhance] org.datanucleus.metadata.InvalidMetaDataException: Class
com.newsplore.weather.bo.UsForecast has property weatherIconByCode declared in MetaData,
 but its getter method doesnt exist in the class!
  [enhance]     at org.datanucleus.metadata.ClassMetaData
.populateMemberMetaData(ClassMetaData.java:497)</pre>
<p>So a domain object (UsForecast) has a property called weatherIconByCode. Hmm, I didnt remember of such property but looking at the source I saw that the offender was a private utility method called getWeatherIconByCode(String code) that was being processed by the enhancer as if it was a property (I&#8217;m using annotations bound to getters and not to fields). Since adding @Transient didn&#8217;t fix it, the solution is to rename the method not to start with get/set (or move it in an utility class which you shouldn&#8217;t do if you follow DDD).<br />
To my relief, after this fix the build didn&#8217;t yield any more errors so I had a nice webapp folder ready to be deployed. AppEngine has a local sandbox (based on Jetty) that should be used before deploying into the cloud. You can start the appserver using an ant target but I chose to get more control and create a script that accomplishes the same thing. Here it is:</p>
<pre>cd build/webapp
java -classpath &lt;appengine-sdk-home&gt;/lib/appengine-tools-api.jar
com.google.appengine.tools.development.DevAppServerMain --port=8080 --address=localhost</pre>
<p>Save this in a file called startgae.sh (mind the path, you should be able to cd to the webapp folder from it) then make it executable.<br />
Using this script I fired-up the container and got no startup error. This was <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">weird</a> since I knew I was using JMX (via Spring and annotations) and as well the task scheduler (using <a href='http://www.opensymphony.com/quartz/'>Quartz</a>) was seemingly up and running.<br />
I hit the home page to see what has been deployed and I get a 404 error. My web.xml has this mapping:</p>
<pre>  &lt;servlet&gt;
    &lt;servlet-name&gt;weather&lt;/servlet-name&gt;
    &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
	&lt;servlet-name&gt;weather&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;</pre>
<p>but this doesn&#8217;t work in the local servlet container. This was quite annoying as not only the home page doesn&#8217;t work, the static folders (css/, js/, img/) are routed through the weather servlet too. Surprisingly as it turns out, this mapping worked perfectly in the AppEngine environment. To be able to continue with the work in the local environment, I had to define fine grained mappings for all the URLs.<br />
After this change, the first URL that started working was the /faq which provided the first breakthrough. Although only the presentation tier is in use on the /faq page, the fact that the page worked provided a bunch of good news: Spring 3.0 DI container, SiteMesh, Spring Security and SpringAOP were all correctly running. </p>
<p>Stay tuned for the <a href='http://blog.newsplore.com/?p=1205'>second part</a> detailing more JPA, datastore indexing, a bunch of the AppEngine limitations, a bit of local environment hacking and how to use &#8220;request welding&#8221; to accomplish long running tasks.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/05/27/reviewing-google-appengine-for-java-part-1" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/05/27/reviewing-google-appengine-for-java-part-1/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Selecting location data from a spatial database</title>
		<link>http://blog.newsplore.com/2009/04/04/selecting-location-data-from-a-spatial-database</link>
		<comments>http://blog.newsplore.com/2009/04/04/selecting-location-data-from-a-spatial-database#comments</comments>
		<pubDate>Sat, 04 Apr 2009 15:52:57 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[mapping]]></category>
		<category><![CDATA[spatial DB]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1031</guid>
		<description><![CDATA[I have been thinking to write about this subject a while back when project Spincloud was still under development. I was even thinking about making this the first post on my blog. The idea is simple: you have location-based data (POIs for instance) stored in some database (preferably a spatial DB) and now you want [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F04%2F04%2Fselecting-location-data-from-a-spatial-database"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F04%2F04%2Fselecting-location-data-from-a-spatial-database" height="61" width="51" /></a></div><p>I have been thinking to write about this subject a while back when project <a href="http://spincloud.com">Spincloud</a> was still under development. I was even thinking about making this the first post on my blog.<br />
The idea is simple: you have location-based data (POIs for instance) stored in some database (preferably a spatial DB) and now you want to perform a select statement that will indicate the area that should include the points we want. In case of Spincloud&#8217;s weather map, we want the weather reported by the stations located within a given area determined by the Google Map viewport that the user is currently browsing.<br />
In all my examples I&#8217;ll use <a href="http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html">SQL Spatial Extensions</a> support, specifically MSQL spatial extensions.<br />
Here&#8217;s a visual representation of the spatial select (the red grid is the area where we want to fetch the data):</p>
<p><img class="alignnone size-full wp-image-1032" src="http://blog.newsplore.com/wp-content/uploads/2009/04/select_smpl.png" alt="select_smpl" width="258" height="256" /></p>
<p>This is quite easy to accomplish by issuing a spatial select statement on the database:</p>
<pre>select * from POI where Contains(GeomFromText
    ('POLYGON ((-30 32, 30 -8, -89 -8, -89 32, -30 32))', LOCATION))</pre>
<p>But what about selecting an area that crosses the 180 degrees longitude? Let&#8217;s say we want to select data in an area around New Zealand that starts at 170 degrees latitude and ends at -160 degrees latitude going East. The selected area will look like this:<br />
<span id="more-1031"></span><br />
<img src="http://blog.newsplore.com/wp-content/uploads/2009/04/nz_box.png" alt="nz_box" width="457" height="345" class="alignnone size-full wp-image-1062" /></p>
<p>If we are to describe this with a polygon, we may be tempted write it like this using Spatial SQL parlance:</p>
<pre>
POLYGON ((-160 -23, -160 -55, 170 -55, 170 -23, -160 -23))
</pre>
<p>but you&#8217;d be wrong. In fact this polygon describes an area on the map that <i>excludes</i> exactly our area of interest:<br />
<img src="http://blog.newsplore.com/wp-content/uploads/2009/04/torsel.png" alt="torsel" width="507" height="156" class="alignnone size-full wp-image-1048" /></p>
<p>This happens specifically because the 180 degrees meridian is crossed (the next point of longitude beyond 180 degrees is -180 degrees).<br />
To fix this special case, you have to test for this occurrence and if so we&#8217;ll construct two polygons, split by the 180 degrees meridian (notice the exaggerated division between the polygons east and west of the 180&deg;):</p>
<p><img src="http://blog.newsplore.com/wp-content/uploads/2009/04/nz_box_split.png" alt="nz_box_split" width="272" height="152" class="alignnone size-full wp-image-1063" /></p>
<p>Two spatial selects will have to be issued in order to account for areas on each side of the 180&deg; meridian.</p>
<p>If you&#8217;re using Google Maps then you most likely use <a href='http://code.google.com/apis/maps/documentation/reference.html#GLatLngBounds'>getBounds()</a> to get the bounding box. The API reference specifically states that the returned box is &#8220;a rectangle in geographical coordinates, including one that crosses the 180 degrees meridian&#8221;. I use the excellent <a href='http://www.vividsolutions.com/jts/jtshome.htm'>Vividsolutions JTS</a> for all GIS related code so to construct the polygons I use the following logic:</p>
<pre>
public List getPOIsInArea(float neLng, float neLat, float swLng, float swLat) {
  GeometryFactory gf = new GeometryFactory();

  if((neLng &lt; swLng) ) { //cross lat or long 180 degree boundary
   Polygon eastPol = gf.createPolygon(gf.createLinearRing(new Coordinate[] {
    new Coordinate(neLng, neLat),
    new Coordinate(-180, neLat),
    new Coordinate(-180, swLat),
    new Coordinate(neLng, swLat),
    new Coordinate(neLng, neLat)
     }), new LinearRing[]{});

   Polygon westPol = gf.createPolygon(gf.createLinearRing(new Coordinate[] {
    new Coordinate(swLng, swLat),
    new Coordinate(180, swLat),
    new Coordinate(180, neLat),
    new Coordinate(swLng, neLat),
    new Coordinate(swLng, swLat)
     }), new LinearRing[]{});

     //select POIs inside both eastPol and westPol
  } else {
      Polygon pol = gf.createPolygon(gf.createLinearRing(new Coordinate[] {
     new Coordinate(neLng, neLat),
     new Coordinate(neLng, swLat),
     new Coordinate(swLng, swLat),
     new Coordinate(swLng, neLat),
     new Coordinate(neLng, neLat),
     }), new LinearRing[]{});

     //select POIs from pol
  }
}
</pre>
<p>The above code creates two polygons if the 180&deg; meridian is crossed (E longitude is greater than the W longitude for the bounding box):</p>
<pre>
East polygon:
POLYGON ((-160 -23, -180 -23, -180 -55, -160 -55, -160 -23))

West polygon:
POLYGON ((160 -55, 180 -55, 180 -23, 160 -23, 160 -55))
</pre>
<p>Both polygons will be used when selecting POIs from the database. The resulted POI list will be of course the union between the POIs in the east and west polygons.</p>
<p>What&#8217;s remaining is to present the data on the map but since the spatial select may return more points than the maximum we want to show on the map (i.e. 1000 returned versus 20 we want shown), we&#8217;ll have to employ some balanced point reduction step (we call it clustering) before the POIs are presented on the map. I&#8217;ll talk about point clustering and using the cool <a href='http://en.wikipedia.org/wiki/K-means_algorithm'>k-means</a> algorithm in a future post.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/04/04/selecting-location-data-from-a-spatial-database" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/04/04/selecting-location-data-from-a-spatial-database/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Evaluating EclipseLink 1.1</title>
		<link>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11</link>
		<comments>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11#comments</comments>
		<pubDate>Sun, 22 Mar 2009 00:34:53 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[opinions]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=981</guid>
		<description><![CDATA[As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for Spincloud, I decided to try out another one. I had tried OpenJPA (spawned from Kodo JDO) when they only supported build-time bytecode enhancement and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11" height="61" width="51" /></a></div><p align='justify'>As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for <a href="http://spincloud.com">Spincloud</a>, I decided to try out another one. I had tried <a href="http://openjpa.apache.org/">OpenJPA</a> (spawned from Kodo JDO) when they only supported <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_build">build-time bytecode enhancement</a> and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s  now an <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_runtime">agent</a> to provide on-the-fly enhancement but I&#8217;ll take transparent enhancement anytime.<br />
I&#8217;ve heard about EclipseLink before. The project started when Oracle donated the respectable <a href="http://www.oracle.com/technology/tech/java/newsletter/articles/toplink/history_of_toplink.html">TopLink project</a> to the Eclipse foundation. If the solid reputation behind TopLink was a good enough argument for me to try it, the announcement that <a href="http://eclipselink.blogspot.com/2008/03/eclipselink-to-provide-jpa-20-reference.html">it will be the JPA 2.0 reference implementation</a> convinced me that I should try it out.<br />
My goal is to evaluate if EclipseLink is production-ready. I&#8217;m applying a complex set of evaluation criteria (joking): if it can run Spincloud then it is (I was inspired by Seifer&#8217;s <a href="http://www.infoq.com/presentations/seifer-ruby-vm-comparison">interview on Infoq</a> about Ruby VMs; when asked what was the criteria for qualifying if a Ruby VM is production ready, he answered: if it runs Rails).</p>
<p>I have the following JPA requirements:<br />
- column mappings, one-to-one, one-to-many<br />
- supports BLOB fields<br />
- supports NamedQueries and NamedNativeQueries<br />
- support for object cache and query cache<br />
- deployment/operational nice to have: ease of maintaining compatibility with both  EclipseLink and Hibernate in the source code and runtime. Ideally I should plug-in any JPA provider without changing a single line of code. This was not attainable as I&#8217;ll explain below.</p>
<p>I started by downloading the binaries</a>. I&#8217;m using Maven to bring the jars so I&#8217;ve followed the instructions <a href="http://wiki.eclipse.org/EclipseLink/Maven">here</a>. I only changed the version since I wanted to use v1.1.0:</p>
<pre>
  &lt;dependency&gt;
    &lt;groupId&gt;org.eclipse.persistence&lt;/groupId&gt;
    &lt;artifactId&gt;eclipselink&lt;/artifactId&gt;
    &lt;version&gt;1.1.0&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
</pre>
<p>There&#8217;s a single jar file called eclipselink-1.1.0.jar downloaded which is a nice change from the multitude of Hibernate jars I was accustomed with.<br />
<span id="more-981"></span><br />
Next, I created a new persistence.xml file since I didn&#8217;t know how different it would be from the one tied to Hibernate. Initially I just changed the JPA provider to:</p>
<pre>
  &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
</pre>
<p>as the documentation stated.<br />
Then I had a look at my current NamedQueries and NamedNativeQueries that looked like this:</p>
<pre>
@org.hibernate.annotations.NamedQueries({
	@org.hibernate.annotations.NamedQuery(name="findStationByPK",
	        query="select station from Station station where station.id=:stationPK"
	        , cacheable=true, cacheRegion="weatherStationsRegion"),
...
</pre>
<p>and I recalled that I did this in order to make use of Hibernate&#8217;s Query cache facility, alas a non-standard way of cache enablement (not until JPA 2.0 anyway). I had to put query caching to rest and switched all my Named*Queries to standard JPA:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station where id=:stationPK"),
...
</pre>
<p> I&#8217;m not using the integration unit tests I have due to the issues I had with the <a href="http://static.springframework.org/spring/docs/2.0.x/reference/testing.html#integration-testing">Spring integration test framework</a> I&#8217;m using after switching to Spring 3.0 so I&#8217;m using ad-hoc testing for now.  After rebuilding/deploying the project I didn&#8217;t notice any error on Tomcat start-up so I just tried the GUI, displaying the weather in a map area. I hit the first error:</p>
<pre>
Exception [EclipseLink-7060] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [java:comp/env/ds/MeteoDS].
Internal Exception: javax.naming.NamingException: This context must be accessed
throughout a java: URL
</pre>
<p>I dug through the documentation (what&#8217;s with this documentation and what does <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Limitations_to_JPA">&#8220;No dynamic weaving (instrumentation) &#8211; static weaving of entities is still available via EclipseLink&#8221;</a> means, why JPAEclipseLinkSessionCustomizer example is broken and finally why use teh deprecated SessionCustomizer?) and found that I have to use a <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Session_Customizer">session customizer</a> to make it work in Tomcat. I didn&#8217;t like this one bit (it just works in Hibernate) but I followed the instructions and EclipseLink could establish the connection with the Tomcat-configured data source as expected. This was the first duly noted turn-off.<br />
I redeployed and browsed the weather map just to hit another problem:</p>
<pre>
  Exception Description: Syntax error parsing the query [findStationByPK:
    select station from   Station where id=:stationPK], line 1, column 28:
    syntax error at [where].
 Internal Exception: MismatchedTokenException(65!=66)
</pre>
<p>Hmm, no compile-time JPA query check. Not good. I checked the JPA query, it was:</p>
<pre>
  @javax.persistence.NamedQuery(name="findStationByPK",
       query="select station from Station where id=:stationPK"),
...
</pre>
<p>which looked OK but looking closely I realized that it was not. The correct syntax is (notice the <b>station.</b> indirection:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station <b>station</b> where <b>station</b>.id=:stationPK"),
	@javax.persistence.NamedQuery(name="findByStationId",
...
</pre>
<p>Hibernate was happy with the &#8220;non-standard&#8221; syntax while EclipseLink is not. No big deal, it wasn&#8217;t in many places anyway. I scanned all my queries and fixed them. Redeployed and hit this:</p>
<pre>
  Exception Description: Syntax error parsing the query [findByStationId: from
    Station station where station.stationId=:stationId], line 1, column 0:
    unexpected token [from].
</pre>
<p>My JPA query is:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="from Station station where station.stationId=:stationId")
</pre>
<p>Again a Hibernate artifact. H3 supports the convenience of using queries that start with &#8220;from entity&#8230;&#8221; if they return entities (single or lists). The fix was simply to add &#8220;select station&#8221; in front of the JPA QL:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="<b>select station</b> from Station station where
                station.stationId=:stationId")
</pre>
<p>Not a biggie either, standard is better and Hibernate can parse this kind of query. Again, rebuilt/redeployed and queried the map again. This time the error was this:</p>
<pre>
[EL Warning]: 2009-03-21 19:02:42.135--UnitOfWork(2001070194)--Exception [EclipseLink-4002]
(Eclipse Persistence Services -
 1.1.0.r3639-SNAPSHOT): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for the right syntax to use
near ':area) , LOCATION) and obs_time
&gt; :minSynopDateToConsiderStr UNION select distin' at line 1
Error Code: 1064
Call: <b>select distinct STATION_FK as STATION_IDENTIFIER, LOCATION,
obs_time as REPORT_TIME  from SYNOP where Contains(GeomFromText(:area) , LOCATION) and
obs_time &gt; :minSynopDateToConsiderStr UNION
select distinct STATION_FK as STATION_IDENTIFIER,
LOCATION, REPORT_TIME as REPORT_TIME from METAR where
Contains(GeomFromText(:area) , LOCATION) and REPORT_TIME &gt; :minMetarDateToConsiderStr</b>
</pre>
<p>I couldn&#8217;t find anything at first in the documentation (getting really pissed at the documentation style, can&#8217;t find anything useful) but I finally found <a href="//wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_Named_Parameters_in_a_Native_Query">this</a>:</p>
<pre>
Support for the EclipseLink # convention is helpful if you are already familiar with
EclipseLink queries or if you are migrating EclipseLink queries to a JPA application.
</pre>
<p>I&#8217;m not &#8220;already familiar with EclipseLink queries&#8221; and no, it&#8217;s not helpful. So now I have to use #area instead of :area named parameter. This is really smart. Why in the world would one want to change the column with sharp? I&#8217;m starting to suspect clumsiness or plain careless coding. I still want to maintain Hibernate/EclipseLink pluggability so I have no choice but creating a static class that holds all NamedNativeQueries and parametrizes the named parameter prefix:</p>
<pre>
class NativeQueries {
public final static String WEATHER_SNAPSHOT_IN_AREA_NATIVE_QUERY ="select distinct
STATION_FK as STATION_IDENTIFIER, LOCATION, obs_time as REPORT_TIME from SYNOP where
Contains (GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
 ", LOCATION) and obs_time &gt; <font color="red">@named-param-prefix@</font>minSynopDateToConsiderStr UNION " +
"select distinct STATION_FK as STATION_IDENTIFIER, LOCATION, REPORT_TIME
as REPORT_TIME from METAR where Contains(GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
", LOCATION) and REPORT_TIME &gt; <font color="red">@named-param-prefix@</font>minMetarDateToConsiderStr";
...
}
</pre>
<p>Then I have to use ant to perform a pre-compilation task that replaces <font color="red">@named-param-prefix@</font> with either : or #. This really got the best of me as I&#8217;ve hit a Java compilation quirk too: you have to delete all classes that rely on the NativeQueries class since they will not recompile if the values of the <b>public static final String</b> values change; you have to delete all .class files and force a full compilation for them.<br />
After I did this build change it all started working. Victory at last. Or was it? Well, no; I still have to add query caching as I heavily use spatial queries to fetch area weather (activated every time the map is dragged/zoomed). There&#8217;s the <a href="http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_EclipseLink_JPA_Extensions_for_Entity_Caching">@Cache</a> but it&#8217;s for entity caching which is good but what I also need is query caching à la Hibernate: </p>
<pre>
 @org.hibernate.annotations.NamedQuery(name="qName", query="&lt;query&gt;",
    <font color="red">cacheable=true, cacheRegion="some-cache-region"</font>)
</pre>
<p align='justify'>
After another round of thorough search of the documentation I <a href="http://wiki.eclipse.org/Using_Advanced_Query_API_%28ELUG%29#Using_Queries_and_the_Cache">found what I needed</a> but it wasn&#8217;t what I expected. EclipseLink doesn&#8217;t support annotation-level query cache configuration. Instead you have to code-in (or use AOP to) cache writes after the queries are executed, via its ReadQuery class.<br />
Needless to say I didn&#8217;t do it. I gave up on it right there.<br />
On a whole this felt a lot like my (undocumented) evaluation I did over a year ago with OpenJPA (no dice too). Poor documentation (worse than EL&#8217;s) and lack of (then) runtime weaving made it a nightmare to deploy. I haven&#8217;t tried it ever since.</p>
<p>Prognosis: negative</p>
<p>This is really a shame, EclipseLink seems to be quite fast and has a footprint similar to Hibernate but:<br />
- the documentation is awful. Guys, look at Hibernate and follow their lead. I badly need a single page HTML up-to-date documentation that I can freely browse. I can find almost anything in a matter of seconds using Hibernate&#8217;s single page HTML doc and Ctrl-F. I feel so strongly about this, I&#8217;d make an addition to the <a href="http://manifesto.softwarecraftsmanship.org/">Software Craftsmanship Manifesto:</a> <b>&#8220;Maintain top-notch documentation&#8221;</b>. Spring and Hibernate projects got it right and this is one of the secrets of their success. Take note.<br />
- Use : (column) for named parameters in NamedNativeQuery; it is consistent with NamedQuery syntax (and hopefully standardized in JPA 2.0).<br />
- Use compile-time Named*Query syntax check. It adds a great deal to predictability.<br />
- Add the Session Customizer fix into of the base platform and make it transparent to the user. Nobody wants to write integration code to fix oddities of popular containers. &#8220;Out of the box&#8221; is valuable.<br />
- Work on a better query caching support or push hard for a JPA 2.0 beta since there&#8217;s standardized second-level caching.</p>
<p>Oh and guys, <a href="http://wiki.eclipse.org/Introduction_to_EclipseLink_Queries_(ELUG)">some</a> documentation pages don&#8217;t render properly on Safari, the TOCs overlap the content. Unacceptable.</p>
<p>Until then I&#8217;m sticking with Hibernate 3.3. It just works.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Choosing a Java hosting provider</title>
		<link>http://blog.newsplore.com/2009/03/14/choosing-a-java-hosting-provider</link>
		<comments>http://blog.newsplore.com/2009/03/14/choosing-a-java-hosting-provider#comments</comments>
		<pubDate>Sat, 14 Mar 2009 05:38:48 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[hosting]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=880</guid>
		<description><![CDATA[Selecting a web hosting provider is a tough job for any web developer that wants to put a Java/JEE web application online. The choice is much simpler when it comes to publishing a PHP web site and there are a load of cheap (and sometimes quite reliable) PHP hosting providers to choose from with LAMP [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F14%2Fchoosing-a-java-hosting-provider"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F14%2Fchoosing-a-java-hosting-provider" height="61" width="51" /></a></div><p>Selecting a web hosting provider is a tough job for any web developer that wants to put a Java/JEE web application online. The choice is much simpler when it comes to publishing a PHP web site and there are a load of cheap (and sometimes quite reliable) PHP hosting providers to choose from with <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP</a> being the de facto standard in the web hosting world. But when it comes to Java hosting providers the picture becomes blurrier. The common thing that all these environments need is a Java container. The most popular choice is Tomcat but there are providers that use Resin, Weblogic or Websphere (the latter two are full fledged JEE containers).<br />
With the raise of lightweight J2EE servers started by the <a href='http://springframework.org'>Spring</a> folks, a little revolution began in the Java world: running enterprise-grade JEE webapps without the need for an EJB container; a servlet container is enough. Tomcat should fill the bill for just about any Java web application that doesn&#8217;t use EJBs. The advantage that comes from running a servlet container is the smaller footprint compared with an EJB container. This is critical when it comes to selecting hosting environments since you&#8217;re paying for resources (especially RAM) that have to be sized to accommodate the memory requirements of the web application.</p>
<p><i>Self hosting: Home-based dedicated server (near $0)</i></p>
<table>
<tr>
<td><img class="alignnone size-full wp-image-916" src="http://blog.newsplore.com/wp-content/uploads/2009/03/homepc.png" alt="homepc" width="136" height="206" /></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td valign='top'>You can use your home internet connection and a PC where the web container runs and deploys your web application. There is an obvious advantage since the server is physically located close to the development team: complete control and physical access to the machine. The other big plus is the price: you&#8217;re already paying for the internet connection and chances are you already have a PC that can be transformed into a server. And chances are that you already have a development environment that can be the basis of the production deployment. Here are the shortcomings:</p>
<p>- Bandwidth limitations: the webserver where the webapp lives will <em>upload</em> content to the web browsers that access the application. The upload bandwidth is smaller than the download bandwidth and will result in longer load times for web clients.<br />
- Some internet providers cap the internet traffic so you may run beyond the limit.
</td>
</tr>
</table>
<p>- You may violate contractual obligations you agreed with your Internet provider by running your own web server.<br />
- The internet connection is not reliable: provider&#8217;s downtime directly translates in downtime for your webapp.<br />
<span id="more-880"></span></p>
<div style='height:14px'></div>
<p><i>Managed hosting ($6 and up)</i><br />
This is the cheapest solution but it poses the most restrictions. The main limitation is the inability to deploy webapps that depend on Java bytecode manipulation at runtime, mainly Hibernate and Spring. This is due to classloading security constraints that prevent the bytecode manipulation libraries (CGLIB or javassist) to perform runtime code enhancements.<br />
Working with managed hosting environments poses more limitations:<br />
- Deployment: some popular hosting providers deploy once a day: you drop the war file or the exploded war in a specific folder on the hosted environment and it will be deployed at a specific time picked by the provider (more <a href="http://help.godaddy.com/topic/319/article/67">here</a>). If it fails, you have to wait another day till the app will be redeployed or pick a provider that supports instant drop&amp;deploy.<br />
- Debugging a failed deployment: I couldn&#8217;t make log4j write the log into a location on my hosted file space so I had to resort to a <a href="http://www.dankomannhaupt.de/projects/index.html">JDBC appender</a> to actually see what causes a failed deployment. This required two deployments (one to try a location on  the hosted folder and a second one to use the JDBC appender; that&#8217;s two days due to the deployment constraint detailed above) and the issue turned out to be the classloader security issue preventing CGLIB to change the bytecode. I have only tried to deploy a war file with Hibernate and Spring dependencies in Godaddy&#8217;s Java hosting environment (their <a href="http://www.godaddy.com/gdshop/hosting/shared.asp?ci=9009">Linux Deluxe plan</a>) before I gave up on managed Java hosting.<br />
- Sharing the environment with other webapps. Your app will be deployed along with other applications and compete for the same resources.<br />
- Access to server logs and traffic stats is very limited. You can only use Google Analytics (or similar) but not <a href="http://awstats.sourceforge.net/">Awstats</a> (at least not for free).<br />
- Outgoing traffic may be restricted or blocked.</p>
<div style='height:16px'></div>
<p align="justify"><b>Unmanaged hosting solutions</b><br />
Unmanaged doesn&#8217;t necessarily mean that the hosting company doesn&#8217;t manage anything, they just leave the actual OS administration in your hands so you&#8217;ll have a physical server under your complete control, everything else from network management to hardware maintenance is done by the hosting company. You/your team has to have solid server administration knowledge: Linux, Apache, Java AppServers, software firewall (iptables), backup/restore, monitoring, security, patching, DNS and more. A web administrator inside your team usually takes care of all these details. After the machine is up and running you are free to install and run any Java container and deploy your application.<br />
Below are the options when choosing to run a dedicated server.
<div style='height:14px'></div>
<p><i>Colocated server ($70 and up)</i></p>
<table>
<tr>
<td><img src="http://blog.newsplore.com/wp-content/uploads/2009/03/mountcolo.png" alt="mountcolo" width="233" height="173" class="alignnone size-full wp-image-942" /></td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td>You can <a href="http://en.wikipedia.org/wiki/Colocation_centre">colocate</a> the server which means that you buy then ship your own rack-mountable server to a data centre where it will be installed by on-site technicians. The monthly fee you&#8217;ll pay starts at around $70 (prices are per one unit which is a slot in the rack) and includes the rack space rental, network connectivity, location security, 24/7 power (not counting <a href="http://www.techcrunch.com/2007/11/12/quick-plug-the-internet-back-in-major-rackspace-outage/">mishaps</a>), etc. Denial of Service prevention services are usually provided as part of the package.<br />
There is complete freedom in terms of the deployment environment since you own it. However, there are two problems that come with this solution:</td>
</tr>
</table>
<p>- Initial cost associated with buying rack-mountable servers that usually start from $1.5k (check <a href="http://www.supermicro.com">SuperMicro</a>, they&#8217;re good). These machines contain redundant components to cope with failures.<br />
- Maintenance: When components break you have to manage their replacement. If the whole machine crashes then your website will be offline until the machine is replaced.</p>
<div style='height:14px'></div>
<p><i>Rent a dedicated server ($100 and up)</i></p>
<table>
<tr>
<td><img src="http://blog.newsplore.com/wp-content/uploads/2009/03/fullrack.png" alt="fullrack" width="106" height="143" class="alignnone size-full wp-image-937" /></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td valign='top'>Instead of buying your own server, you can choose to rent a dedicated server from the hosting provider. Kevin Rose unveils how digg.com was initially hosted on dedicated servers rented from <a href="http://www.ev1servers.net/">Ev1Servers.net</a> (see full <a href="http://www.ev1servers.net/">article</a>). The benefit of this solution is the lower initial cost compared to colocation, beginning at around $100/month and of course the complete control over the environment. The drawbacks are the same as colocation except for servicing the box that falls under the hosting provider&#8217;s responsibility.</td>
</tr>
</table>
<div style='height:14px'></div>
<p align="justify"><i> Virtual Private Server ($20 and up)</i></p>
<table>
<tr>
<td><img src="http://blog.newsplore.com/wp-content/uploads/2009/03/vpsnodes.png" alt="vpsnodes" width="129" height="234" class="alignnone size-full wp-image-944" /></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td valign='top'>A <a href="http://en.wikipedia.org/wiki/Virtual_private_server">VPS</a> &#8221; is a method of partitioning a physical server computer into multiple servers&#8221;. Each of these partitions behaves like a full fledged server, has an IP address and can be reachable from the internet. The computers that are VPS partitioned, sit on the hosting provider&#8217;s infrastructure. The provider is responsible for network connectivity, bandwidth and continuity of service in case  of physical server failure. There are two main VPS software providers: Virtuozzo and Xen. Of the two, I recommend Xen-based VPS providers since the virtualized machines cannot be oversold and thus you&#8217;ll get consistent performance for the money (a detailed explanation <a href="http://www.hostcube.com/blog/virtuozzo-vs-xen">here</a>). The main benefit of the VPS is the excellent price/performance ratio starting as low as $20/month. Another big advantage is the ability to &#8220;resize&#8221; the virtual partition on demand in a matter of minutes (you&#8217;ll pay more of course), add more virtual machines to your deployment () as well as &#8220;relocating&#8221; it to a different data center </td>
</tr>
</table>
<p>if the provider has multiple locations (West Coast and East Coast for instance). Root access is also provided. The drawbacks are:<br />
- the operating systems that you can run are controlled by the hosting provider and usually are Linux distributions (here&#8217;s an <a href="https://www.linode.com/faq.cfm">example</a>). However, the choices are very popular Linux distros.<br />
- you have to have server administration expertise.<br />
I run this blog, <a href="http://spincloud.com">spincloud.com</a> and the rest of my web properties on a VPS. I use the excellent <a href="http://linode.com">Linode</a> after I had switched from <a href="http://slicehost.com">Slicehost</a>, having performance issues. I am quite happy with Linode, their service rocks and they&#8217;ve been delivering consistent performance since day one.</p>
<div style='height:14px'></div>
<p><i>Cloud services (EC2: $100 and up)</i></p>
<table>
<tr>
<td><img src="http://blog.newsplore.com/wp-content/uploads/2009/03/cloud.png" alt="cloud" width="138" height="119" class="alignnone size-full wp-image-953" /></td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td valign='top'>Cloud computing is today&#8217;s trend. The company that kick-started the trend was Amazon with their <a href="http://aws.amazon.com/ec2/">Elastic Computing Cloud</a>. EC2 is actually an advanced form of VPS: you can run your own virtual machine image (or AMI) or pick one from the existing stock. After the AMI is booted and configured, you have the liberty of installing any Java environment. You get root access too.<br />
From the high profile websites, <a href="http://smugmug.com">Smugmug</a> uses EC2 and S3 and they <a href="http://blogs.smugmug.com/don/2006/11/10/amazon-s3-show-me-the-money/">save money</a> doing so. In fact Smugmug was one of the early adopters of Amazon&#8217;s cloud services.</td>
</tr>
</table>
<p>Drawbacks:<br />
- If you reboot the machine or if it simply crashes then all data is lost, including any database records you happen to have. This was a real problem for developers until Amazon added the possibility to <a href="http://www.infoq.com/news/2008/04/amazon-storage">mount a persistent S3 volume</a> in an EC2 instance. S3 stands for <a href="http://aws.amazon.com/s3/">Simple Storage Service</a> and is Amazon&#8217;s offering for cloud-based storage.<br />
- You have to learn new terminology and set of skills that are applicable to Amazon&#8217;s problem-set only. You&#8217;ll also tie the solution to a single vendor.<br />
The cost for an EC2+S3 starts at close to $100/month.<br />
<del datetime="2009-05-19T23:21:20+00:00">If you&#8217;re thinking of using the dirt-cheap (starts free) <a href='http://code.google.com/appengine/'>Google AppEngine</a> for deploying a Java application you&#8217;re out of luck, they only support Python.</del> Update: Google has added Java support to Appengine.  at the begining of April. I have a dev account and I&#8217;ll evaluate it in a separate post.</p>
<p><b>Common concerns when selecting a hosting provider</b><br />
<i>Price</i><br />
Don&#8217;t pick a service just because it&#8217;s cheap. Perform some due diligence on the company, where their data centers are located and how good their service is. You don&#8217;t want your website hosted on the wrong side of the world. Monitor <a href='http://www.webhostingtalk.com/'>WebHostingTalk forums</a>; hosting providers often run promotions there.<br />
Look for monthly plans and don&#8217;t commit to yearly plans since you may end-up being unhappy with the provider and with no choice to get out of the contract.<br />
Be suspicious when you see associated setup fees coming with setting-up an account. They are not refundable and good hosting providers simply don&#8217;t have them.</p>
<p><i>Uptime</i><br />
You want no interruption in service for your web servers so <a href="http://en.wikipedia.org/wiki/Uptime">uptime</a> is a must. You can&#8217;t afford to have downtime since it translates directly into lost customers and ultimately lost business. Look for hosting providers that offer SLAs (Service level agreements) and have proven reliability. <a href="http://netcraft.com">Netcraft</a> is a neat tool that measures the reliability of hosting providers on a monthly basis. Look for the providers that guarantee five nines (99.999%) uptime, that is five minutes <i>a year</i>.</p>
<p><i>Technical support</i><br />
My personal experience is that I used the tech support while I was using a shared web hosting. I haven&#8217;t used any after moving to the VPS.</p>
<p><i>Transfer volume</i><br />
Perform some basic calculations for the required traffic based on the expected traffic and data volume sent out. Providers bundle 200GB/month or more in their offerings these days. This should be enough for most of the cases. Make sure your website doesn&#8217;t get cut-off if your traffic spikes and/or you&#8217;re not paying a ridiculous amount of money per GB if you go beyond your quota.</p>
<p><i>Security</i><br />
All hosting providers offer a form of protection against DDOS but you are responsible for the software that runs on the server. I got the online forum I was running for <a href='http://newsplorer.com'>Newsplorer</a> hacked a couple of years ago because I didn&#8217;t upgrade the forum software to patch a security vulnerability that was promptly exploited.</p>
<p><i>Backup</i><br />
Hosting providers offer backups or you can do it yourself with a bit of effort and some cron knowledge. Save the backed-up files on a different location (I use S3 for my backup needs but there are <a href='http://skydrive.live.com/'>free solutions</a> too).</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/03/14/choosing-a-java-hosting-provider" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/03/14/choosing-a-java-hosting-provider/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
