RestEasy Boss unable to scan Web-Inf for Jax-RS annotations - jboss

i get the error: Unable to scan WEB-INF for JAX-RS annotations, you must manually register your classes/resources
I have the following maven config:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<version>3.0.4.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.2.14.Final</version>
</dependency>
My java class is a minimalistic call.
#Path("test")
public class MyResource {
// #Inject
// private JpaUserDao userDao;
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#GET
#Produces(MediaType.TEXT_XML)
public String getIt() {
System.out.printf("");
return "Got it!";
}
}
I want to marry rest easy with cdi. In my web app i enabled the scan config, because i want that the annotation #path is found automatically.
My web.xml
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>

You are using restEasy 3.0.+ so use a design pattern like singleton to initiate your webservice.
#ApplicationPath("/mainPathToWebService")
public class singletonHelper extends Application {
#SuppressWarnings("unchecked")
public Set<Class<?>> getClasses() {
return new HashSet<Class<?>>(Arrays.asList(MyResource.class));
}
}

Related

org.apache.shiro.web.filter.authc.LogoutFilter is already configured in ShiroWebModule

I'm using Shiro 1.7.1 and Guice 4.2.3, below is the snippet of my POM file,
<properties>
<shiro.version>1.7.1</shiro.version>
<guice.version>4.2.3</guice.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-guice</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
...
</dependencies>
I'm customizing Shiro's LogoutFilter by creating a new class,
package com.myshiro.myshiro;
import org.apache.shiro.web.filter.authc.LogoutFilter;
public class MyLogoutFilter extends LogoutFilter {
}
and bind org.apache.shiro.web.filter.authc.LogoutFilter to the above customized MyLogoutFilter,
package com.myshiro.myshiro;
public class MyShiroModule extends ShiroWebModule {
public MyShiroModule(ServletContext servletContext) {
super(servletContext);
}
protected void configureShiroWeb() {
try {
bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
} catch (NoSuchMethodException e) {
addError(e);
}
bind(org.apache.shiro.web.filter.authc.LogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", LOGOUT);
}
}
and I try to create the Guice injector in the unit test class like this,
public class MyShiroModuleTest {
#Mock
private ServletContext servletContext;
#Test
public void test() {
Guice.createInjector(new MyShiroModule(servletContext));
}
}
and it failed with the following errors,
1) Binding to null instances is not allowed. Use toProvider(Providers.of(null)) if this is your intended behaviour.
at org.apache.shiro.guice.web.ShiroWebModule.configureShiro(ShiroWebModule.java:136)
2) A binding to org.apache.shiro.web.filter.authc.LogoutFilter was already configured at com.myshiro.myshiro.MyShiroModule.configureShiroWeb(MyShiroModule.java:25).
at org.apache.shiro.guice.web.ShiroWebModule.setupFilterChainConfigs(ShiroWebModule.java:209)
From the second note above, it explained that the binding to org.apache.shiro.web.filter.authc.LogoutFilter is already configured in both MyShiroModule and ShiroWebModule. Do you have any idea of how to bind to my customized LogoutFilter?
This issue did not happened in Shiro 1.3.x.
My sample project is available here, you can see the error simply when you mvn clean install.
Sounds like your problem is related to Guice 4, and less about Shiro. Instead of re-using the same binding key, define a new one, something like:
bind(MyLogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", Key.get(MyLogoutFilter.class));

Apache Camel routing API call to message queue

I have two applications that talk to each other using a REST API.
I would like to know if I can use Apache Camel as a proxy that could "persist" the API calls, for example storing them as messages in ActiveMQ, and then later route the requests to the actual API endpoint.
Practically, I would like to use Apache Camel to "enhance" the API endpoints adding persistence, throttling of requests, etc...
What component do you suggest to use?
You can always try to bridge your HTTP request into a queue, but making the thread wait by forcing the exchangePattern to InOut.
See this example :
import org.apache.activemq.broker.BrokerService;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(SimpleRouteBuilder.class);
public static void main(String[] args) throws Exception {
org.apache.camel.main.Main main = new org.apache.camel.main.Main();
main.addRouteBuilder(new SimpleRouteBuilder());
logger.info("Next call is blocking, ctrl-c to exit\n");
main.run();
}
}
class SimpleRouteBuilder extends RouteBuilder {
private static final Logger logger = LoggerFactory.getLogger(SimpleRouteBuilder.class);
public void configure() throws Exception {
// launching an activemq in background
final BrokerService broker = new BrokerService();
broker.setBrokerName("activemq");
broker.addConnector("tcp://localhost:61616");
Runnable runnable = () -> {
try {
broker.start();
} catch (Exception e) {
e.printStackTrace();
}
};
runnable.run();
// receiving http request but queuing them
from("jetty:http://127.0.0.1:10000/input")
.log(LoggingLevel.INFO, logger, "received request")
.to("activemq:queue:persist?exchangePattern=InOut"); // InOut has to be forced with JMS
// dequeuing and calling backend
from("activemq:queue:persist")
.log(LoggingLevel.INFO, logger,"requesting to destination")
.removeHeaders("CamelHttp*")
.setHeader("Cache-Control",constant("private, max-age=0,no-store"))
.to("jetty:http://perdu.com?httpMethod=GET");
}
}
If you are using maven, here is the pom.xml :
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>be.jschoreels.camel</groupId>
<artifactId>camel-simple</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
<version>5.15.3</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-kahadb-store -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>

Rest service Java, error using jersey dependency

I getting started with Java and rest services, i created a rest service with GET method, this method return a UserVO with his properties, im set properties values with random values using setMethods and return object but this not work mapping object to json of jersey. I using tomcat 6, JDK 1.8.0_121 and eclipse and show this error:
com.sun.jersey.spi.container.ContainerResponse write
GRAVE: A message body writer for Java class Autoconsulta.ValueObject.UsuarioVO, and Java type class Autoconsulta.ValueObject.UsuarioVO, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
VO
public class UsuarioVO {
private String rut;
private boolean isValid;
public String getRut() {
return rut;
}
public void setRut(String rut) {
this.rut = rut;
}
public boolean isValid() {
return isValid;
}
public void setValid(boolean isValid) {
this.isValid = isValid;
}
}
my ret service:
#GET
#Path("/getUser")
#Produces({MediaType.APPLICATION_JSON})
public UsuarioVO getUsuario() {
UsuarioVO u = new UsuarioVO();
u.setRut("123444");
u.setValid(true);
return u;
}
web xml
<servlet>
<servlet-name>Servicio_Rest</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>Autoconsulta.ws.rest.service</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Servicio_Rest</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
pom xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>

spring mvc rest protocol buffers http 406 not acceptable error

I am using Spring MVC 4.1.5 with its REST support trying to get a web service working with google protocol buffers message format. I have seen a lot of posts that are mentioning this issue with JSON format but none with google protocol buffers format.
Also I don't see Spring framework docs have a MediaType for protobufs (more on that below) My code is posted here on github
Here's my controller code (using or not using produces="application-xprotobuf" makes no difference - same 406 not acceptable error)
#RestController
#RequestMapping("/ws")
#EnableWebMvc
public class CustomerRestController {
#Autowired
private CustomerRepository customerRepository;
//#RequestMapping(value="/customers/{id}", method = RequestMethod.GET, produces="application/x-protobuf")
#RequestMapping(value="/customers/{id}", method = RequestMethod.GET)
public CustomerProtos.Customer customer(#PathVariable Integer id) {
return this.customerRepository.findById(id);
}
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
private CustomerProtos.Customer customer(int id, String f, String l, Collection<String> emails) {
String emailAddressString = "defaultEmail#address.com";
for (String email : emails) {
emailAddressString = email;
break;
}
EmailAddress emailAddress = CustomerProtos.Customer.EmailAddress.newBuilder()
.setType(CustomerProtos.Customer.EmailType.PROFESSIONAL).setEmail(emailAddressString).build();
return CustomerProtos.Customer.newBuilder().setFirstName(f).setLastName(l).setId(id).addEmail(emailAddress)
// .addAllEmail(emailAddresses)
.build();
}
#Bean
CustomerRepository customerRepository() {
return new CustomerRepositoryImpl();
}
}
here's my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>demo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/rest-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Here's my pom.xml, please note that i do have google protobuf libaries added here and they do end up in WEB-INF/lib folder of the deployed .war file.
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.DemoApplication</start-class>
<java.version>1.8</java.version>
<jackson.version>2.5.3</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-legacy</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here's my test client
package demo;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class DemoApplicationTests {
#Configuration
public static class RestClientConfiguration {
#Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
return new RestTemplate(Arrays.asList(hmc));
}
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
#Autowired
private RestTemplate restTemplate;
#Test
public void contextLoaded() {
ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
"http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2", CustomerProtos.Customer.class);
System.out.println("customer retrieved: " + customer.toString());
}
}
When I run the client from command line using mvn test
I get the following error
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.697 sec <<< FAILURE! - in demo.DemoApplicationTests
contextLoaded(demo.DemoApplicationTests) Time elapsed: 0.037 sec <<< ERROR!
org.springframework.web.client.HttpClientErrorException: 406 Not Acceptable
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:289)
at demo.DemoApplicationTests.contextLoaded(DemoApplicationTests.java:42)
I saw people suggesting using a contentNegotiationManager
In my rest-servlet.xml I have mvc:annotation-driven tag
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="demo" />
<mvc:annotation-driven />
</beans>
Also I have dropped in a webConfig.java in demo package
package demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Total customization - see below for explanation.
*/
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.TEXT_PLAIN).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON).
mediaType("x-protobuf", MediaType.ALL)
;
}
}
I get the 406 not acceptable error with and without the webconfig.java (which is doing the work of contentNegotationManager).
I haven't been able to find a MediaType.APPLICATION_XPROTOBUF in Spring 4.1.3 or even 4.2.3 jars .
So I have left that value to MediaType.ALL ( I think that should work ?)
When I run the test client I get this message before actually running the test..
09:27:26.198 [main] DEBUG o.s.web.client.RestTemplate - Created GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2"
09:27:26.199 [main] DEBUG o.s.web.client.RestTemplate - Setting request Accept header to [application/x-protobuf, text/plain, application/xml, application/json]
09:27:26.245 [main] DEBUG o.s.web.client.RestTemplate - GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2" resulted in 406 (Not Acceptable); invoking error
handler
It clearly shows its setting the accept headers to include "application-xprotobuf" value as well.
Not sure what I am missing in this case.
I had the same issue with the controller failing with 406: Not Acceptable. After a lot of tracing I figured out the statement in the example:
Spring Boot automatically registers HttpMessageConverter beans so we need only define the ProtobufHttpMessageConverter bean and it gets configured appropriately.
is to be understood literally, since without Spring Boot no converter registration happens. The bean is instantiated, but it's never registered in the list of HttpMessageConverters.
I've solved it by explicitly registering a ProtobufHttpMessageConverter instance:
#Configuration
#EnableWebMvc
#ComponentScan
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ProtobufHttpMessageConverter());
super.configureMessageConverters(converters);
}
}
You don't need to declare a separate bean for it (unless you plan to call it explicitly).
Also note that overriding configureMessageConverters() disables all standard converters; if you mean to extend the list of stock converters rather than replace it, override extendMessageConverters() instead.

Getting error on pubsub example using Atmosphere + Jersey

I'm following the tutorial here
http://jfarcand.wordpress.com/2011/06/29/rest-websocket-applications-why-not-using-the-atmosphere-framework/
I already have a Jersey project up and running and working fine using JBoss 7. The one difference i have is that i am using Jersey with Spring. So my JQueryPubSub looks like this
#Service <-- For Spring component Scan
#Path("/pubsub/{topic}")
#Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {
#PathParam("topic")
Broadcaster topic;
#GET
public SuspendResponse<String> subscribe() {
return new SuspendResponse.SuspendResponseBuilder<String>()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
#POST
#Broadcast
public Broadcastable publish(#FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
}
So i wanted to add this example but i'm getting
22:55:27,381 SEVERE [com.sun.jersey.spi.inject.Errors] (MSC service thread 1-3) The following errors and warnings have been detected with resource
and/or provider classes:
SEVERE: Missing dependency for field: org.atmosphere.cpr.Broadcaster com.order.resources.JQueryPubSub.topic
Any ideas how i can fix this issue and why Jersey seems to be aggressively injecting the value into broadcaster??
I had the same problem and was able to fix it by updating jersey jars from 1.4 to 1.6
If you use maven, you can add the following dependencies.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
Answering after long time..but people who are trying can still take some advantage out of this
You can try with the following .
I just tried and it worked for me
Step-1
If you are using weblogic 12 c make the following change
function subscribe() {
var request = {
url :document.location.origin+'/<your-context-path>/ws/pubsub/' + getElementByIdValue('topic'),
Step-2
In web.xml add the below configuration
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*******package name where your handler is**********</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter
</param-value>
</init-param>
<init-param>
<param-name>WEBSOCKET_PROTOCOL_EXECUTION</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/pubsub/*</url-pattern>
</servlet-mapping>
step-3
paste the below code in a java file in the package you defined in the above step(also can be found in the git site of atmosphere)
import java.io.IOException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Singleton;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.handler.AtmosphereHandlerAdapter;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.SimpleBroadcaster;
#Singleton
#AtmosphereHandlerService(path = "/{chat}",
interceptors = {
AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class,
BroadcastOnPostAtmosphereInterceptor.class,
SuspendTrackerInterceptor.class},
broadcaster = SimpleBroadcaster.class)
public class AtmosphereHandler extends AtmosphereHandlerAdapter {
#Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
if (event.isSuspended()) {
String message = event.getMessage() == null ? null : event.getMessage().toString();
if (message != null && message.indexOf("message") != -1) {
event.getResource().write(message.substring("message=".length()));
} else {
event.getResource().write("=error=");
}
}
}
}
Now deploy the ear it works..
Jar files
atmosphere-annotations-2.1.1.jar
atmosphere-jersey-2.1.1.jar
atmosphere-runtime-2.1.1.jar
atmosphere-weblogic-2.1.1.jar
commons-collections-3.2.1.jar
commons-dbutils-1.5.jar
commons-io-2.4.jar
jersey-core-1.17.1.jar
jersey-json-1.17.1.jar
jersey-server-1.17.1.jar
jersey-servlet-1.17.1.jar
log4j-1.2.15.jar