I started by downloading RESTEasy 1.2.1 GA and tried the sample code. I started with a java client to access existing RESTful Web Services and APIs. Among the api-clients, there is a Twitter small client that works out-of-the box (located under /RESTEASY_1_2_1_GA/examples/api-clients/src/main/java/org/jboss/resteasy/examples/twitter).
However when I started to extract the code and wanted to create a Maven 2 based stand-alone project, I encountered some issues related to JAR dependency conflicts, including the following error message also described here.
java.lang.NoClassDefFoundError: Could not initialize class com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl
The project (eclipse) structure looks as below:
I managed to fix these issues by modifying the POM file as follow:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.jboss.resteasy.examples</groupId> <artifactId>api-clients</artifactId> <version>1.2.1.GA</version> <dependencies> <!-- Resteasy Core --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> </dependency> <!-- JAXB support --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxb-provider</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-bom</artifactId> <version>1.2.1.GA</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- Build Settings --> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <!-- Environment Settings --> <repositories> <repository> <id>jboss</id> <name>jboss repo</name> <url>http://repository.jboss.org/maven2</url> </repository> </repositories> </project>
The most important piece, beside the cleaning of the POM file, was to include a pom that can be imported so the versions of the individual modules do not have to be specified (see RESTEasy documentation - Chapter 43. Maven and RESTEasy).
I also made sure to have correct dependencies for resteasy-jaxrs and resteasy-jaxb-provider.
As a result, I was able to compile the whole project without any errors (mvn clean compile) and run it to access the Twitter REST API
mvn exec:java -Dexec.mainClass="org.jboss.resteasy.examples.twitter.TwitterClient" -Dexec.args="<userid> <password>"(Replace last parameters by your twitter user and password).
The small client in question leverages JAX-RS annotations to read and write the Twitter API resources:
package org.jboss.resteasy.examples.twitter; import java.util.Date; import java.util.List; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.jboss.resteasy.client.ProxyFactory; import org.jboss.resteasy.client.ClientExecutor; import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor; import org.jboss.resteasy.plugins.providers.RegisterBuiltin; import org.jboss.resteasy.spi.ResteasyProviderFactory; public class TwitterClient { static final String friendTimeline = "http://twitter.com/statuses/friends_timeline.xml"; public static void main(String[] args) throws Exception { RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); final ClientExecutor clientExecutor = new ApacheHttpClientExecutor(createClient(args[0], args[1])); TwitterResource twitter = ProxyFactory.create(TwitterResource.class, "http://twitter.com", clientExecutor); System.out.println("===> first run"); printStatuses(twitter.getFriendsTimelines()); twitter .updateStatus("I programmatically tweeted with the RESTEasy Client at " + new Date()); System.out.println("===> second run"); printStatuses(twitter.getFriendsTimelines()); } public static interface TwitterResource { @Path("/statuses/friends_timeline.xml") @GET Statuses getFriendsTimelines(); @Path("/statuses/update.xml") @POST Status updateStatus(@FormParam("status") String status); } private static void printStatuses(Statuses statuses) { for (Status status : statuses.status) System.out.println(status); } private static HttpClient createClient(String userId, String password) { Credentials credentials = new UsernamePasswordCredentials(userId, password); HttpClient httpClient = new HttpClient(); httpClient.getState().setCredentials(AuthScope.ANY, credentials); httpClient.getParams().setAuthenticationPreemptive(true); return httpClient; } @XmlRootElement public static class Statuses { public List<Status> status; } @XmlRootElement public static class Status { public String text; public User user; @XmlElement(name = "created_at") @XmlJavaTypeAdapter(value = DateAdapter.class) public Date created; public String toString() { return String.format("== %s: %s (%s)", user.name, text, created); } } public static class User { public String name; } }
The small DateAdapter class is a utility class for date formatting:
package org.jboss.resteasy.examples.twitter; import java.util.Date; import java.util.List; package org.jboss.resteasy.examples.twitter; import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.jboss.resteasy.util.DateUtil; public class DateAdapter extends XmlAdapter<String, Date> { @Override public String marshal(Date date) throws Exception { return DateUtil.formatDate(date, "EEE MMM dd HH:mm:ss Z yyyy"); } @Override public Date unmarshal(String string) throws Exception { try { return DateUtil.parseDate(string); } catch (IllegalArgumentException e) { System.err.println(String.format( "Could not parse date string '%s'", string)); return null; } } }
No comments:
Post a Comment