users@jersey.java.net

Re: [Jersey] Issue with SpringServlet

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Fri, 11 Jul 2008 09:45:32 +0200

Hi Peter,

great that it's working! :)

As you wrote in your previous mail, there's still the issue with
multiple beans of the same super type. I'll have a look at this the next
days.

Cheers,
Martin


On Thu, 2008-07-10 at 13:09 -0700, Peter Liu wrote:
> Hi Martin,
>
> Please ignore my previous email. I found what I was missing. I need to
> add the @Autowire
> annotation on my subresources in order for the SpringComponentProvider to
> create the Spring bean. After doing that, it works like a charm.
>
> This is great! The code is clean and I don't have to deal with configuring
> the ServiceLocatorFactoryBean.
>
> Thanks for all your help.
>
> Peter
>
> Peter Liu wrote:
> > Hi Martin,
> >
> > I just tried the ResourceContext approach as you suggested. However,
> > it doesn't
> > quite do what I want. The subresource returned from ResourceContext does
> > have the UriInfo injected by Jersey but it doesn't seem to be managed
> > by Spring.
> > For example, it doesn't have the EntityManager and transaction
> > injected by
> > Spring. Am I missing something or is this not supported by Jersey?
> >
> > If not supported, it seems to me that there needs to be a Spring
> > version of the ResourceContext
> > that creates an instance of the Spring bean and does the Jersey
> > injection. This will give the best of both world.
> >
> > Note that this approach is really promising because I no longer have
> > to add bean
> > definitions to the applicationContext.xml (including using @Autowire
> > which I just discovered)
> > which solves my initial problem with the bean name lookup.
> > Peter
> >
> > Peter Liu wrote:
> >> Martin Grotzke wrote:
> >>> Hi Peter,
> >>>
> >>> I just had a short look at your sources, thanx for sending them. Now I
> >>> have a better idea what you want to achieve, but I need some time to
> >>> reproduce the issue and write tests for this.
> >>>
> >>> Just one hint what you might try alternatively...
> >>>
> >>> As you already mentioned, you're creating new subresources using
> >>> Spring's ServiceLocatorFactoryBean.
> >>>
> >>> As an alternative, you might use jersey's ResourceContext, which you
> >>> can
> >>> inject with @Context. The ResourceContext was introduced to allow
> >>> developers to get an instance of some subresource from the
> >>> IoC-container
> >>> so that he can use features like e.g. AOP provided by the IoC-container
> >>> also for subresources.
> >>>
> >>> With this, you would not have to set the UriInfo "by hand" on your
> >>> subresource, but the subresource could get the UriInfo injected by
> >>> jersey when it's fetched from the ResourceContext. This prevents you
> >>> from injecting stuff into the root resource that is only required in
> >>> subresources...
> >>>
> >>> I don't know how the ServiceLocatorFactoryBean is working actually, but
> >>> perhaps using the ResourceContext changes your situation?
> >>>
> >> Thanks for letting me know about the ResourceContext. I am going to
> >> give it a try and I think
> >> it will work. However, the main issue still remains. I still have to
> >> define multiple beans for the
> >> root class and subclasses and it will cause the getBeanName() to
> >> throw an exception.
> >>
> >> Peter
> >>
> >>> Cheers,
> >>> Martin
> >>>
> >>>
> >>> On Wed, 2008-07-09 at 13:59 -0700, Peter Liu wrote:
> >>>> Hi Martin,
> >>>>
> >>>> Attached is a NB project containing the source. The application
> >>>> is a CRUD application that uses Spring,
> >>>> Jersey and JPA. Take a look at x.service.DiscountCodeResource which
> >>>> has a static inner class CustomersSubresource which extends
> >>>> CustomersResource. Both CustomersSubresource
> >>>> and CustomersResource have bean definitions in
> >>>> applicationContext.xml. Also, take a look a
> >>>> DiscountCodeResource.getCustomerCollectionResource() which is a
> >>>> subresource locator method that
> >>>> returns a prototype instance of CustomresSubresource via Spring's
> >>>> ServiceLocatorFactoryBean mechanism.
> >>>>
> >>>> Peter
> >>>>
> >>>>
> >>>> Martin Grotzke wrote:
> >>>>
> >>>>> Hi Peter,
> >>>>>
> >>>>> please can you send a complete example for this, including the
> >>>>> resource
> >>>>> classes? Perhaps we need to extend existing concepts of jerseys
> >>>>> support
> >>>>> of IoC...
> >>>>>
> >>>>> Thanx && cheers,
> >>>>> Martin
> >>>>>
> >>>>>
> >>>>> On Tue, 2008-07-08 at 16:32 -0700, Peter Liu wrote:
> >>>>>
> >>>>>> Martin Grotzke wrote:
> >>>>>>
> >>>>>>> Hi Peter,
> >>>>>>>
> >>>>>>> if I understood you correctly, you want to configure multiple
> >>>>>>> beans for
> >>>>>>> the same class.
> >>>>>>>
> >>>>>>> For this issue we introduced the "value" attribute of the @Inject
> >>>>>>> annotation. With this it's possible to have multiple spring
> >>>>>>> beans of the
> >>>>>>> same class which can be used like this:
> >>>>>>>
> >>>>>>>
> >>>>>>> @Inject( "bean1" )
> >>>>>>> private Bean _bean1;
> >>>>>>> @Inject( "bean2" )
> >>>>>>> private Bean _bean2;
> >>>>>>>
> >>>>>>>
> >>>>>>> <bean id="bean1" class="some.spring.Bean" />
> >>>>>>> <bean id="bean2" class="some.spring.Bean" />
> >>>>>>>
> >>>>>>>
> >>>>>>> Does this solve your issue, or did I get s.th. wrong?
> >>>>>>>
> >>>>>> Unfortunately, I can't used the @Inject mechanism. What I am
> >>>>>> trying to do is to have a root
> >>>>>> singleton resource return a different "prototype" instance of a
> >>>>>> subresource when calling
> >>>>>> the subresource locator method. on the root resource. I am
> >>>>>> achieving this by using Spring's ServiceLocatorFactoryBean
> >>>>>> mechanism. It just happens that the subresource class can be a
> >>>>>> subclass of the root resource
> >>>>>> class. For example, my configuration may look as follow:
> >>>>>>
> >>>>>> <bean id="rootResource" class="x.RootResource"/>
> >>>>>> <bean id="subresource" class="x.SubclassOfRootResource"
> >>>>>> type="prototype"/>
> >>>>>>
> >>>>>> This will cause the getBeanName() to throw an exception because
> >>>>>> springContext.getBeanNamesForType(x.RootResource)
> >>>>>> will return both rootResource and subresource. However, in this
> >>>>>> case, it is really the rootResource that
> >>>>>> I want.
> >>>>>>
> >>>>>> Peter
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>> Cheers,
> >>>>>>> Martin
> >>>>>>>
> >>>>>>>
> >>>>>>> On Tue, 2008-07-08 at 11:53 -0700, Peter Liu wrote:
> >>>>>>>
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> I have been trying out the spring-jersey integration and ran
> >>>>>>>> into an issue where the
> >>>>>>>> SpringServlet will not work if I configure multiple beans, one
> >>>>>>>> for the root resource class and one for
> >>>>>>>> each subclass of the root class. The
> >>>>>>>> SpringServlet.getBeanName() will throw an exception
> >>>>>>>> since it thinks that there are multiple beans configured for
> >>>>>>>> the same class.
> >>>>>>>>
> >>>>>>>> I made some changes to SpringServlet.getBeanName() (see
> >>>>>>>> attached file).
> >>>>>>>> In the case where there are multiple bean names returned for a
> >>>>>>>> given class,
> >>>>>>>> before throwing an error, I look for the bean instance that has
> >>>>>>>> the exact
> >>>>>>>> same class as the one being looked up. With this change, I am
> >>>>>>>> able to
> >>>>>>>> make application work.
> >>>>>>>>
> >>>>>>>> I would like to submit this change to jersey-spring. Please let
> >>>>>>>> me know if the change
> >>>>>>>> is acceptable or there is a better way to solve this problem.
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks.
> >>>>>>>>
> >>>>>>>> Peter
> >>>>>>>> plain text document attachment (SpringServlet.java)
> >>>>>>>> /*
> >>>>>>>> * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> >>>>>>>> * * Copyright 2007 Sun Microsystems, Inc. All rights
> >>>>>>>> reserved. * * The contents of this file are subject to the
> >>>>>>>> terms of the Common Development
> >>>>>>>> * and Distribution License("CDDL") (the "License"). You may
> >>>>>>>> not use this file
> >>>>>>>> * except in compliance with the License. * * You can obtain
> >>>>>>>> a copy of the License at:
> >>>>>>>> * https://jersey.dev.java.net/license.txt
> >>>>>>>> * See the License for the specific language governing
> >>>>>>>> permissions and
> >>>>>>>> * limitations under the License.
> >>>>>>>> *
> >>>>>>>> * When distributing the Covered Code, include this CDDL Header
> >>>>>>>> Notice in each
> >>>>>>>> * file and include the License file at:
> >>>>>>>> * https://jersey.dev.java.net/license.txt
> >>>>>>>> * If applicable, add the following below this CDDL Header,
> >>>>>>>> with the fields
> >>>>>>>> * enclosed by brackets [] replaced by your own identifying
> >>>>>>>> information:
> >>>>>>>> * "Portions Copyrighted [year] [name of copyright owner]"
> >>>>>>>> */
> >>>>>>>> package x.service;
> >>>>>>>>
> >>>>>>>> import com.sun.jersey.spi.service.ComponentContext;
> >>>>>>>> import java.io.IOException;
> >>>>>>>> import java.lang.annotation.Annotation;
> >>>>>>>> import java.lang.reflect.Constructor;
> >>>>>>>> import java.lang.reflect.InvocationTargetException;
> >>>>>>>> import java.util.Arrays;
> >>>>>>>> import java.util.Collection;
> >>>>>>>> import java.util.Iterator;
> >>>>>>>>
> >>>>>>>> import javax.servlet.ServletException;
> >>>>>>>> import javax.servlet.ServletRequest;
> >>>>>>>> import javax.servlet.ServletResponse;
> >>>>>>>>
> >>>>>>>> import org.apache.commons.logging.Log;
> >>>>>>>> import org.apache.commons.logging.LogFactory;
> >>>>>>>> import org.springframework.aop.framework.Advised;
> >>>>>>>> import org.springframework.aop.support.AopUtils;
> >>>>>>>> import org.springframework.context.ApplicationContext;
> >>>>>>>> import org.springframework.context.ConfigurableApplicationContext;
> >>>>>>>> import org.springframework.web.context.WebApplicationContext;
> >>>>>>>> import
> >>>>>>>> org.springframework.web.context.support.WebApplicationContextUtils;
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> import com.sun.jersey.api.core.ResourceConfig;
> >>>>>>>> import com.sun.jersey.spi.container.WebApplication;
> >>>>>>>> import com.sun.jersey.spi.container.servlet.ServletContainer;
> >>>>>>>> import com.sun.jersey.spi.inject.Inject;
> >>>>>>>> import com.sun.jersey.spi.service.ComponentProvider;
> >>>>>>>> import java.lang.reflect.Proxy;
> >>>>>>>>
> >>>>>>>> /**
> >>>>>>>> * TODO: DESCRIBE ME<br>
> >>>>>>>> * Created on: Apr 3, 2008<br>
> >>>>>>>> * * @author <a
> >>>>>>>> href="mailto:martin.grotzke_at_freiheit.com">Martin Grotzke</a>
> >>>>>>>> * @version $Id$
> >>>>>>>> */
> >>>>>>>> public class SpringServlet extends ServletContainer {
> >>>>>>>>
> >>>>>>>> private static final long serialVersionUID =
> >>>>>>>> 5686655395749077671L;
> >>>>>>>> private static final Log LOG =
> >>>>>>>> LogFactory.getLog(SpringServlet.class);
> >>>>>>>>
> >>>>>>>> public static class SpringComponentProvider implements
> >>>>>>>> ComponentProvider {
> >>>>>>>>
> >>>>>>>> /* (non-Javadoc)
> >>>>>>>> * @see
> >>>>>>>> com.sun.ws.rest.spi.service.ComponentProvider#getInjectableInstance(java.lang.Object)
> >>>>>>>>
> >>>>>>>> */
> >>>>>>>> public <T> T getInjectableInstance(T instance) {
> >>>>>>>> if (AopUtils.isAopProxy(instance)) {
> >>>>>>>> final Advised aopResource = (Advised) instance;
> >>>>>>>> try {
> >>>>>>>> @SuppressWarnings("unchecked")
> >>>>>>>> final T result = (T)
> >>>>>>>> aopResource.getTargetSource().getTarget();
> >>>>>>>>
> >>>>>>>> return result;
> >>>>>>>> } catch (Exception e) {
> >>>>>>>> LOG.fatal("Could not get target object from
> >>>>>>>> proxy.", e);
> >>>>>>>> throw new RuntimeException("Could not get
> >>>>>>>> target object from proxy.", e);
> >>>>>>>> }
> >>>>>>>> } else {
> >>>>>>>> return instance;
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> private ConfigurableApplicationContext springContext;
> >>>>>>>>
> >>>>>>>> public
> >>>>>>>> SpringComponentProvider(ConfigurableApplicationContext
> >>>>>>>> springContext) {
> >>>>>>>> this.springContext = springContext;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public <T> T getInstance(Scope scope, Class<T> clazz)
> >>>>>>>> throws InstantiationException,
> >>>>>>>> IllegalAccessException {
> >>>>>>>> return getInstance(null, scope, clazz);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public <T> T getInstance(Scope scope, Constructor<T>
> >>>>>>>> constructor,
> >>>>>>>> Object[] parameters)
> >>>>>>>> throws InstantiationException,
> >>>>>>>> IllegalArgumentException,
> >>>>>>>> IllegalAccessException,
> >>>>>>>> InvocationTargetException {
> >>>>>>>>
> >>>>>>>> return getInstance(null, scope,
> >>>>>>>> constructor.getDeclaringClass());
> >>>>>>>>
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public <T> T getInstance(ComponentContext cc, Scope
> >>>>>>>> scope, Class<T> clazz)
> >>>>>>>> throws InstantiationException,
> >>>>>>>> IllegalAccessException {
> >>>>>>>> final Autowire autowire =
> >>>>>>>> clazz.getAnnotation(Autowire.class);
> >>>>>>>> if (autowire != null) {
> >>>>>>>> if (LOG.isDebugEnabled()) {
> >>>>>>>> LOG.debug("Creating resource class " +
> >>>>>>>> clazz.getSimpleName() + " annotated with @" +
> >>>>>>>> Autowire.class.getSimpleName() + " as spring bean.");
> >>>>>>>> }
> >>>>>>>> /* use createBean to have a fully initialized
> >>>>>>>> bean, including
> >>>>>>>> * applied BeanPostProcessors (in contrast to
> >>>>>>>> #autowire()).
> >>>>>>>> */
> >>>>>>>> final Object result =
> >>>>>>>> springContext.getBeanFactory().createBean(clazz,
> >>>>>>>> autowire.mode().getSpringCode(),
> >>>>>>>> autowire.dependencyCheck());
> >>>>>>>> return clazz.cast(result);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> final String beanName = getBeanName(cc, clazz,
> >>>>>>>> springContext);
> >>>>>>>> if (beanName == null) {
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> /* if the scope is null, this means that jersey
> >>>>>>>> simply doesn't know what's
> >>>>>>>> * the scope of this dependency, so it's left to
> >>>>>>>> the application...
> >>>>>>>> */
> >>>>>>>> if (scope == Scope.Undefined || scope ==
> >>>>>>>> Scope.Singleton && springContext.isSingleton(beanName) || scope
> >>>>>>>> == Scope.PerRequest && springContext.isPrototype(beanName)) {
> >>>>>>>> if (LOG.isDebugEnabled()) {
> >>>>>>>> LOG.debug("Retrieving bean '" + beanName +
> >>>>>>>> "' for resource class " + clazz.getSimpleName() + " from
> >>>>>>>> spring.");
> >>>>>>>> }
> >>>>>>>> Object result = springContext.getBean(beanName);
> >>>>>>>>
> >>>>>>>> if (result instanceof Proxy && result
> >>>>>>>> instanceof Advised) {
> >>>>>>>> try {
> >>>>>>>> result = ((Advised)
> >>>>>>>> result).getTargetSource().getTarget();
> >>>>>>>> } catch (Exception ex) {
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> return clazz.cast(result);
> >>>>>>>> } else {
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public void inject(Object instance) {
> >>>>>>>> }
> >>>>>>>> };
> >>>>>>>>
> >>>>>>>> @Override
> >>>>>>>> protected void initiate(ResourceConfig rc, WebApplication
> >>>>>>>> wa) {
> >>>>>>>> try {
> >>>>>>>> final WebApplicationContext springContext =
> >>>>>>>> WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> wa.initiate(rc, new
> >>>>>>>> SpringComponentProvider((ConfigurableApplicationContext)
> >>>>>>>> springContext));
> >>>>>>>> } catch (RuntimeException e) {
> >>>>>>>> LOG.error("Got exception while trying to
> >>>>>>>> initialize", e);
> >>>>>>>> throw e;
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> /* (non-Javadoc)
> >>>>>>>> * @see
> >>>>>>>> javax.servlet.http.HttpServlet#service(javax.servlet.ServletRequest,
> >>>>>>>> javax.servlet.ServletResponse)
> >>>>>>>> */
> >>>>>>>> @Override
> >>>>>>>> public void service(ServletRequest req, ServletResponse
> >>>>>>>> res) throws ServletException, IOException {
> >>>>>>>> LOG.debug("Starting...");
> >>>>>>>> try {
> >>>>>>>> super.service(req, res);
> >>>>>>>> } catch (RuntimeException e) {
> >>>>>>>> LOG.error("Caught exception.", e);
> >>>>>>>> }
> >>>>>>>> LOG.debug("Finished.");
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> private static String getBeanName(ComponentContext cc,
> >>>>>>>> Class<?> c, ApplicationContext springContext) {
> >>>>>>>> System.out.println("getBeanName() c = " + c + " cc = "
> >>>>>>>> + cc);
> >>>>>>>>
> >>>>>>>> boolean annotatedWithInject = false;
> >>>>>>>> if (cc != null) {
> >>>>>>>> final Inject inject =
> >>>>>>>> getAnnotation(cc.getAnnotations(), Inject.class);
> >>>>>>>> if (inject != null) {
> >>>>>>>> annotatedWithInject = true;
> >>>>>>>>
> >>>>>>>> if (inject.value() != null &&
> >>>>>>>> !inject.value().equals("")) {
> >>>>>>>> System.out.println("inject.value = " +
> >>>>>>>> inject.value());
> >>>>>>>> return inject.value();
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> final String names[] =
> >>>>>>>> springContext.getBeanNamesForType(c);
> >>>>>>>>
> >>>>>>>> if (names.length == 0) {
> >>>>>>>> return null;
> >>>>>>>> } else if (names.length == 1) {
> >>>>>>>> return names[0];
> >>>>>>>> } else {
> >>>>>>>> for (int i = 0; i < names.length; i++) {
> >>>>>>>> String name = names[i];
> >>>>>>>> Object bean = springContext.getBean(name);
> >>>>>>>> Class clazz = null;
> >>>>>>>>
> >>>>>>>> if (bean instanceof Advised) {
> >>>>>>>> clazz = ((Advised)
> >>>>>>>> bean).getTargetSource().getTargetClass();
> >>>>>>>> } else {
> >>>>>>>> clazz = bean.getClass();
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> if (clazz == c) {
> >>>>>>>> return name;
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> final StringBuilder sb = new StringBuilder();
> >>>>>>>> sb.append("There are multiple beans configured in
> >>>>>>>> spring for the type ").append(c.getName()).append(".");
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> if (annotatedWithInject) {
> >>>>>>>> sb.append("\nYou should specify the name of the
> >>>>>>>> preferred bean at @Inject: Inject(\"yourBean\").");
> >>>>>>>> } else {
> >>>>>>>> sb.append("\nAnnotation information was not
> >>>>>>>> available, the reason might be because you're not using " +
> >>>>>>>> "@Inject. You should use @Inject and
> >>>>>>>> specifiy the bean name via Inject(\"yourBean\").");
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> sb.append("\nAvailable bean names:
> >>>>>>>> ").append(toCSV(names));
> >>>>>>>>
> >>>>>>>> throw new RuntimeException(sb.toString());
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> private static <T extends Annotation> T
> >>>>>>>> getAnnotation(Annotation[] annotations,
> >>>>>>>> Class<T> clazz) {
> >>>>>>>> if (annotations != null) {
> >>>>>>>> for (Annotation annotation : annotations) {
> >>>>>>>> if (annotation.annotationType().equals(clazz)) {
> >>>>>>>> return clazz.cast(annotation);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static <T> String toCSV(T[] items) {
> >>>>>>>> if (items == null) {
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>> return toCSV(Arrays.asList(items));
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static <I> String toCSV(Collection<I> items) {
> >>>>>>>> return toCSV(items, ", ", null);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static <I> String toCSV(Collection<I> items, String
> >>>>>>>> separator, String delimiter) {
> >>>>>>>> if (items == null) {
> >>>>>>>> return null;
> >>>>>>>> }
> >>>>>>>> if (items.isEmpty()) {
> >>>>>>>> return "";
> >>>>>>>> }
> >>>>>>>> final StringBuilder sb = new StringBuilder();
> >>>>>>>> for (final Iterator<I> iter = items.iterator();
> >>>>>>>> iter.hasNext();) {
> >>>>>>>> if (delimiter != null) {
> >>>>>>>> sb.append(delimiter);
> >>>>>>>> }
> >>>>>>>> final I item = iter.next();
> >>>>>>>> sb.append(item);
> >>>>>>>> if (delimiter != null) {
> >>>>>>>> sb.append(delimiter);
> >>>>>>>> }
> >>>>>>>> if (iter.hasNext()) {
> >>>>>>>> sb.append(separator);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> return sb.toString();
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> ---------------------------------------------------------------------
> >>>>>>>>
> >>>>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >>>>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >>>>>>>>
> >>>>>> ---------------------------------------------------------------------
> >>>>>>
> >>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >>>>>>
> >>>>>
> >>>> fd
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >>>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net