Category: English
I tried to install Nexus 1.9.2.2 OSS on my Tomcat 7.0.20 with the new Oracle JDK 7. This was not a big success. Ok first of all make sure to use the unpacked version of the nexus war or else it wont be able to find the NEXUS_PLEXUS_WORK environment variable.
Second, you need to patch the unpacked war. Strip out the xstream-1.3 and add the latest snapshot. Also add the latest xmlpull.org API jar to the WEB-INF/lib of the unpacked nexus war.
More info see this JIRA ticket.
DVCS
Distributed version control systems gained a lot of attention over the last few years. There are many hosting providers that offer free DVCS space on the web. But there are situations that you want to run your own private DVCS server and do not want use a publicly and open DVCS like Gitorious, Github or BitBucket. Of-course you can always buy a commercial offering for a private DVCS solution.
The nice thing about a DVCS is that there is not one version, there are multiple ‘versions’ of a source tree. But at some point you do want a central location to store your (releases) sources. In this article I will explain how to setup a Git server on a Windows machine using Apache to server Git request over HTTP.
If you want to know more, Atlassian has an excellent presentation on DVCS, recorded at the Atlassian Summit last June. And Linus Torvalds talk on Git is worth your time: http://www.youtube.com/watch?v=4XpnKHJAok8
msysgit
You will need to install msysgit, I used version msysGit-fullinstall-1.7.6-preview20110708.exe. On my machine I installed msysgit to D:/dev/msysgit
Repositories
Create a directory that contains your Git repositories, for example: D:/dev/repo/git. To get you started, go to the directory and create an empty Git repository.
cd D:/dev/repo/git git init --bare Test.git

Apache configuration
In this tutorial I use Apache 2.2.19. You need to setup git-http-backend.exe in order to serve Git through Apache. First copy ..\msysgit\mingw\bin\libiconv-2.dll to ..\msysgit\libexec\git-core or else you will get a 500 error from Apache. To test if your setup works run ..\msysgit\libexec\git-core\git-http-backend.exe
Add the following to your Apache conf\httpd.conf:
SetEnv GIT_PROJECT_ROOT D:/dev/repo/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAliasMatch \
"(?x)^/(.*/(HEAD | \
info/refs | \
objects/(info/[Apache Git server on Windows^/]+ | \
[0-9a-f]{2}/[0-9a-f]{38} | \
pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
git-(upload|receive)-pack))$" \
"D:/dev/msysgit/libexec/git-core/git-http-backend.exe/$1"
I also made the Apache DocumentRoot point to my Git repos:
DocumentRoot "D:/dev/repo/git"
<Directory "D:/dev/repo/git">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
The result:

Using the repo
You can create a local copy of this git repo using the clone command.
git clone http://localhost/Test.git

Warning
Make sure that you setup authentication if you do not want your sources to become publicly available. This can be done using the regular Apache authentication modules.
Links
Many thanks to: http://www.jeremyskinner.co.uk/2010/07/31/hosting-a-git-server-under-apache-on-windows/
I really like the new SABnzbd 0.6 version, works like a charm. Since they are actively updating it I was doing the service install step manually each time after updating my SABnzbd installation. But more than once I forgot how to register the service and especially that the -f argument needs a path and not a exe file as an argument. Thats why I created a script that does this for me. Want to use the script, create a file called service-installer.cmd, and put the following content in it:
@echo off %~d0 cd %~dp0 net stop SABHelper net stop SABnzbnd SABnzbd-helper.exe remove SABnzbd-service.exe remove SABnzbd-service.exe -f %~dp0 install SABnzbd-helper.exe install net start SABnzbd pause
Now run the script, thats all!
For my current client I am involved in the process of creating a list with allowed, deprecated and blacklisted frameworks and dependencies. I`ve noticed that there are a lot of internal projects that copy dependencies and framework choices from previous projects and are therefore using old and deprecated libraries. We are trying very hard to get projects to use standard APIs and get rid of the old stuff.
Frameworks like Spring, Google Guice, Seam, etc, are also moving toward standard APIs. Spring 3.0 embraces a lot of standards APIs like JSR303, JSR330, JSR317, which in my opinion is a good thing!
Why move to these new APIs?
It allows developers to focus on one API instead of learning a specific API for each framework. Switch or to other/competing frameworks or upgrading becomes easier. For example, the gap between Spring 3 and Java EE 6 (CDI + EJB3) has become much smaller due to these new standards. A good example were standardisation helps is the JSR 303 Bean Validation API which is supported by both Spring, Hibernate/JPA, JSF, etc.
Springmodules validation
In Spring 3 the JSR 303 Beans Validation API support was introduced which effectively replaces the springmodules validation project. Users of Spring 3 are encouraged to use this new JSR 303 Beans Validation API.
More information
When you want to leverage the standard API in your project, please have a look at the following articles:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation
http://www.openscope.net/2010/02/08/spring-mvc-3-0-and-jsr-303-aka-javax-validation/
Spring Dependency Injection annotations
Spring and Google have been working on a standardisation for Dependency Injection annotations, result: the JSR 330 specification. This is a standard API for doing annotation based dependency injection. Spring supports this API since Spring 3.0 (http://blog.springsource.com/2009/09/29/spring-framework-3-0-rc1-released/).
More information
Have a look at the following articles:
http://code.google.com/p/atinject/
http://ralf.schaeftlein.de/2009/11/19/spring-3-0-rc-2-and-jsr-330-dependency-injection-for-java/
Hibernate vs Java Persistence API
The Java Persistence API (JPA) was introduced as part of the Java EE 5 and EJB 3 specification. JPA is in a way the formalisation of Hibernate in a Java Specification (JSR). Since the makers of Hibernate were actively involved in this specification there are numberous of simularities between Hibernate and JPA.
Differences between Hibernate and JPA
JPA defines the standard API for using persistence in Java. You can use Hibernate as a JPA implementation. When using JPA developers can leverage the power of a standardised persistence API and still being able to use Hibernate specific functionality if required. But it opens up possibilities to move to EclipseLink or some other JPA implementation.
Hibernate 3.5 – JPA 2.0
In Hibernate 3.5 a lot of Hibernate subprojects have been merged back into the Hibernate core. This makes it easier to configure and use JPA in conjunction with Hibernate. The JSR 303 API was not officially included as a requirement for JPA 2.0 but Hibernate integrates nicely with the validation specification.
Conclusion
There are a lot of examples that demonstrate the benefits of using standard JSR APIs whenever possible. I would advice to use standard APIs whenever possible and only use specific framework functionality when the standards do not provide enough functionality.
Last month I blogged about the lacking gzip support in the Spring Android RestTemplate. Some collegues at my current client were struggeling invoking gzip encoded RESTful services using Spring 3.0 Web MVCs RestTemplate. While searching the web they found my blog post about Spring RestTemplate and the gzip troubles and decided to ask me for some help
In this article I will explain how to unmarshall a gzip encoded response from RESTful service that uses XML messages.
gzip encoded content
When invoking RESTful services from a client you typically specify in the client request, using HTTP request headers, what the Accept type is (JSON or XML) and content encoding you support as a client. The RESTful service inspects the HTTP request headers and returns the requested content (if supported). This proces is called content negotiation. Have a look at a sample request below:

Not all services support different types of content encoding and/or return types. Sometimes you find yourself in a situation that you have to invoke services that return specific content types or encoding formats, for example compressed content using gzip compression.
In the HTTP Accept-Encoding header you specify the content encoding you are supporting. When invoking services that use gzip encoding you need to specify the Accept-Encoding: gzip,deflate in the request headers. Spring RestTemplate using commons-httpclient does not add this by default and disallows you to invoke services that requires a client supporting gzip encoding, this typically results in a HTTP 400 Bad Request. In this blog I described an option to solve this problem in the RestTemplate, but thats only part of the solution.
Guess what happens when you invoke a RESTful service using Spring Web MVCs RestTemplate and the content body contains gzip encoded content? You are out of luck… or not? Read on…
Gzip Enabled MarshallingHttpMessageConverter
The RESTful service my collegues were invoking returns XML data in the response body. So the return value of the RESTful service is an XML message, this message will be unmarshalled using an XML unmarshaller like JAXB. The way to do this using Spring Web MVCs RestTemplate is by adding a MessageConvertor called MarshallingHttpMessageConverter to your RestTemplate and you are good to go.
The MarshallingHttpMessageConverter takes care of marshalling and unmarshalling messages passing between the client and RESTful service. But if your service returns gzip encoded content this is not enough. Because the text/xml content of the response body is gzip encoded we first need to deflate the content before JAXB2 is able to unmarshall the content. The response below contains response content that is gzip encoded. The tool I used, SoapUI, already deflated the content for me, but when invoking with the RestTemplate you have to do this yourself:

I created a GzipEnabledMarshallingHttpMessageConverter that supports both gzip and non-gzip encoded content. This message convert only works for XML messages that need to be (un)marshalled. For JSON services you need to implement a different solution. In the MessageConverter I perform a check to see if the Content-Encoding actually is gzip encoded, if so, I use a GZipStreamSource to read the Gzip compressed content from the InputStream of the response body.
The implementation below is a combination of the Spring MarshallingHttpMessageConverter and the AbstractXmlMessageConverter. I had to extend the AbstractHttpMessageConverter because the StreamSource is created within this class.
package com.oudmaijer.rest.spring.xml.message.converter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.util.Assert;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.util.List;
import java.util.zip.GZIPInputStream;
/**
* Add gzip decompression support for HttpResponse body's that are encoded with gzip.
* <p/>
* Implements the AbstractHttpMessageConverter in the same way as
* the Spring AbstractXmlMessageConverter and adds the MarshallingHttpMessageConverter
* functionality to it.
*
* @param <T>
*/
public class GzipEnabledMarshallingHttpMessageConverter<T> extends AbstractHttpMessageConverter<T> {
private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
private Marshaller marshaller;
private Unmarshaller unmarshaller;
/**
* Protected constructor that sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
* to {@code text/xml} and {@code application/xml}, and {@code application/*-xml}.
*/
public GzipEnabledMarshallingHttpMessageConverter(Jaxb2Marshaller marshaller, Jaxb2Marshaller unmarshaller) {
super(new MediaType("application", "xml"), new MediaType("text", "xml"), new MediaType("application", "*+xml"));
Assert.notNull(marshaller, "marshaller must not be null");
Assert.notNull(unmarshaller, "unmarshaller must not be null");
this.marshaller = marshaller;
this.unmarshaller = unmarshaller;
}
@Override
public final T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException {
StreamSource streamSource = null;
boolean gzip = false;
HttpHeaders headers = inputMessage.getHeaders();
List<String> contentEncoding = headers.get("Content-Encoding");
if( headers != null && contentEncoding != null ) {
for(String contentEncodingString : contentEncoding) {
if( contentEncodingString != null && "gzip".equalsIgnoreCase(contentEncodingString.trim()) ) {
gzip = true;
}
}
}
if( gzip ) {
streamSource = new GZipStreamSource(inputMessage.getBody());
} else {
streamSource = new StreamSource(inputMessage.getBody());
}
return (T) readFromSource(clazz, inputMessage.getHeaders(), streamSource);
}
@Override
protected final void writeInternal(T t, HttpOutputMessage outputMessage) throws IOException {
writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody()));
}
/**
* Set the {@link Marshaller} to be used by this message converter.
*/
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
/**
* Set the {@link Unmarshaller} to be used by this message converter.
*/
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
@Override
public boolean supports(Class<?> clazz) {
return this.unmarshaller.supports(clazz);
}
/**
*
* @param clazz
* @param headers
* @param source
* @return
* @throws IOException
*/
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws IOException {
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
try {
return this.unmarshaller.unmarshal(source);
} catch (UnmarshallingFailureException ex) {
throw new HttpMessageNotReadableException("Could not read [" + clazz + "]", ex);
}
}
/**
*
* @param o
* @param headers
* @param result
* @throws IOException
*/
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws IOException {
Assert.notNull(this.marshaller, "Property 'marshaller' is required");
try {
this.marshaller.marshal(o, result);
} catch (MarshallingFailureException ex) {
throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex);
}
}
}
The GZipStreamSource comes from an XML library created by Kohsuke Kawaguchi. I made some minor modifications to the code but the credits for this code goes to Kohsuke.
package com.oudmaijer.rest.spring.xml.message.converter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.zip.GZIPInputStream;
import javax.xml.transform.stream.StreamSource;
/**
* {@link StreamSource} that reads from gzip-compressed XML stream.
* <p/>
* THIS SOFTWARE IS IN PUBLIC DOMAIN. NO WARRANTY.
*
* @author Kohsuke Kawaguchi (kk@kohsuke.org)
*/
public class GZipStreamSource extends StreamSource {
/**
* Creates a {@link StreamSource} from a gzip-compressed XML file.
*/
public GZipStreamSource(File file) throws IOException {
this(new FileInputStream(file), file.toURI().toURL().toExternalForm());
}
/**
* Creates a {@link StreamSource} from a gzip-compressed stream.
*/
public GZipStreamSource(InputStream stream) throws IOException {
super(new GZIPInputStream(stream));
}
/**
* Creates a {@link StreamSource} from a gzip-compressed stream.
* <p/>
* <p>This constructor allows the systemID to be set in addition
* to the input stream, which allows relative URIs
* to be processed.</p>
*/
public GZipStreamSource(InputStream stream, String systemId) throws IOException {
super(new GZIPInputStream(stream), systemId);
}
/**
* Creates a {@link StreamSource} from a gzip-compressed stream.
*
* @param url
* @throws IOException
*/
public GZipStreamSource(String url) throws IOException {
this(new URL(url).openStream(), url);
}
}
Spring configuration
And finally you have to configure your RestTemplate to use the new MessageConverter.
<bean id="httpClientFactory" class="org.springframework.http.client.CommonsClientHttpRequestFactory">
<constructor-arg ref="httpClient"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="httpClientFactory"/>
<property name="messageConverters">
<list>
<bean class="com.oudmaijer...GzipEnabledMarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller"/>
<constructor-arg ref="jaxbMarshaller"/>
</bean>
...
</list>
</property>
</bean>
Conclusion
Using this MessageConverter you can invoke RESTful services that return gzip encoded content. Lets hope Spring adds it to the default message converters in the future because gzip compressed content is an elegant solution when you need to return large messages from a RESTful service.