NullPointerException when using CXF SSE by #Context SseEventSink - nullpointerexception

I am trying to use JAX-RS SSE(Server-sent event) feature in Tomcat 8.0.45 and Apache CXF 3.2.8, but always get a NullPointerException when send the GET request from browser via javascript new EventSource(url). Following is the code:
#Path("/sse")
public class SSEService {
#GET
#Path("/test")
#Produces(MediaType.SERVER_SENT_EVENTS)
public void test(#Context Sse sse, #Context SseEventSink eventSink) {
try (SseEventSink sink = eventSink) {
sink.send(sse.newEvent("Hello world"));
}
}
}
The exception:
Caused by: java.lang.NullPointerExecption
at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.initContinuation(AsyncResponseImpl.java:306)
at org.apache.cxf.jaxrs.impl.AsyncResponseImpl.<init>(AsyncResponseImpl.java:68)
at org.apache.cxf.jaxrs.sse.SseEventSinkContextProvider.createContext(SseEventSinkContextProvider.java:47)
......
Thanks for your help!

Related

Enabling Spring OAuth2 ResourceServer disables UsernamePasswordAuthenticationFilter

I have the following in my WebSecurityConfigurerAdaptor:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login.jsp").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedPage("/login.jsp?authorization_error=true")
.and()
.csrf()
.disable()
.formLogin()
.loginProcessingUrl("/login")
.loginPage("/login.jsp")
.failureUrl("/login.jsp?authentication_error=true");
}
I have an OAuth2 client (written in PHP) and can be redirected to /login before getting a valid access token.
Then I try to enable my ResourceServerConfigurerAdapter:
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.resourceId("myResource").stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.requestMatchers()
.antMatchers("/me")
.and()
.authorizeRequests()
.antMatchers("/me").access("#oauth2.hasScope('email')");
}
}
Once the ResourceServer is enabled, the UsernamePasswordAuthenticationFilter is never invoked, and going to /login returns the HTTP 404 error.
I read the sample Spring OAuth2 application sparklr2 and tonr2 many times but I cannot figure out what is wrong with my code.
It is a very difficult bug to track down.
My code initially used Spring Security version 4.0.2.RELEASE and Spring version 4.2.2.RELEASE. Once I changed my maven pom.xml to use Spring Security version 3.2.8.RELEASE and Spring version 4.1.8.RELEASE, my code works.
It may have to do with the following bug:
resource server security custom request matching ignored

#BeanParam does not work with Apache CXF 3.0.x

I am trying to use #BeanParam annotation from JAX-RS.
It was working perfectly fine with Apache cxf 2.7.7 but after upgrading to Apache cxf 3.0.1 it does not work. In my rest service, bean param is null and i get NullPointerException.
I have tried with cxf 3.0.3 but result is same.
My RestService looks like
Class MyService {
#BeanParam
private MyBean params;
#Path("/test")
public Response testIt() {
// params is null here
}
}
class MyBean {
#QueryParam
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
My dependency in gradle looks like
def cxfVersion = "3.0.1"
ext.libraries = [
cxf: [
"org.apache.cxf:apache-cxf:$cxfVersion",
"org.apache.cxf:cxf-rt-frontend-jaxrs:$cxfVersion"
]
Does anybody have any idea what has changed form cxf 2.7.7 to cxf 3.0.x, that will make this non functioning.
I found the problem. It was due to presence of another cxf version jar present on classpath (version 2.3.3) coming from other projects dependencies. Somehow that was getting the precedence over 3.x version and that didn't had support for BeanParam.
Removing that jar from classpath worked for me.

JAX-RS Client API async request

I am trying to use the JAX-RS Client API to request a resource through HTTP GET, by using the following code: (I used jersey-client v2.12 and also resteasy-client v3.0.8.Final to test the implementation)
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.InvocationCallback;
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
client.target("http://example.com/").request().async().get(new InvocationCallback<String>() {
#Override
public void completed(String s) {
System.out.println("Async got: " + s);
}
#Override
public void failed(Throwable throwable) {
System.out.println("Async failure...");
}
});
}
}
As I expected the String is printed almost immediately. But the process keeps running about one minute, although there isn't any code that should be executed.
The JAX-RS spec just says that we should use the InvocationCallback and nothing else that matters to my issue. But even if I use a Future the same effect happens. I also tested, if this has something to do with a timeout, which was very unlikely and wrong. The debugger shows that there are some threads running namely DestroyJavaVM and jersey-client-async-executor-0 or pool-1-thread-1 in the case of resteasy.
Do you have any idea what is going wrong here?
It is allways helpful to consult the JavaDoc. Concerning my issue it says:
Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application. Client instances must be properly closed before being disposed to avoid leaking resources.
If I close the client properly everything is working as expected.
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
// request here
client.close();
}
}

Inject EJB into JAX-RS 2.0 subresource when subresource is got via ResourceContext

I am using Jersey 2.8 with Glassfish 4.0.
I have a resource locator class which looks like below
#Path("/")
#ManagedBean
public class MyServiceLocator {
#Context
ResourceContext rc;//javax.ws.rs.container.ResourceContext
#EJB
private MyEJBHome myEJB;
#Inject//javax.inject.Inject
MySubService mss;
#Path("/mysubservice")
public MySubService getMySubService() {
return rc.getResource(MySubService.class);
//also tried return rc.initResource(new MySubService());
}
}
and a sub resource class which is
#ManagedBean
public class MySubService {
#EJB
public MyEJBHome myEJB;
#Context
HttpHeaders heads;
/*#Inject
private myEJBHome myEJB2;*/
#Path("/mypath")
#GET
#Produces(MediaType.APPLICATION_JSON)
public Object doSomething(#Context SecurityContext securityContext) {...}
}
beans.xml file is put to META-INF and WEB-INF.
In MyServiceLocator class private MyEJBHome myEJB is injected successfully. And MySubService mss object is injected successfully and with EJB injected into it.
The problem is that when MySubService is got via ResourceContext the EJB is not injected into it.
Previously i used Glassfish 3 and Jersey 1.17 with proprietary ResourceContext and absolutely the same code worked ok.
I googled a lot and read a lot of similar (but a bit different) questions and as i understood non JAX-RS stuff (EJB in my case) can't be injected when sub resource is got via ResorceContext. Is it true? If yes how can i work it around?
The one possible solution is to inject sub resource objects to the resource locator class but there are too many of them and it seems to be very ugly.
EDIT Injection with #Inject works if to create a binder, bind ejb class to ejb interface and register that binder. But i don't want to describe binding for hundreds of my ejbs. Also as i understand it is specific binding fir HK2 system and i don't want to be linked to it.
Different actions with setting #Named annotations and trying to inject via CDI didn't help. It seems that when getting sub-resource via ResourceContext Jersey uses only HK2 and that's why CDI can't do it's work. Is that correct?
The only appropriate solution i found was to create my own annotation and inject provider.
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface EJBInject {
String beanName();
}
#Provider
public class EjbInjectProvider implements InjectionResolver<EJBInject> {
#Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
try {
String beanName = injectee.getParent().getAnnotation(EJBInject.class).beanName();
return new InitialContext().lookup("java:global/MyApp/" + beanName);
} catch (Exception e) {
return null;
}
}
#Override
public boolean isConstructorParameterIndicator() {
return false;
}
#Override
public boolean isMethodParameterIndicator() {
return false;
}
}
Then ejb can be injected using that annotation like
#EJBInject(beanName="MyBean")
MyBeanEJBHome myBean;
In such case any standard EJB injections which MyBeanEJBHome might need work correctly, too.

How do I force GlassFish 2 to load EJBs on startup?

We're using EJB3 on GlassFish v2.
My application includes a GenericServlet called StartupServlet, which has an init method. java.util.TimerTask pollers started from this method cannot lookup facades from the InitialContext.
However if I make an HTTP request and do a lookup, it succeeds. Therefore I have a workaround now where my poller startup code makes an HTTP connection to a page which looks up the interfaces they need.
How can I rearrange my application so I don't need to use such a hack? If possible the solution needs to work on GFv3 as well.
Thanks in advance for your help!
On GF 2, I have a servlet that on start ensures that my timer is created. This looks up a remote session bean and calls it successfully from the init() (not actual code, distilled down to the important parts):
#EJB(name="TimerSessionRef", beanInterface=TimerSessionRemote.class)
public class StartTimers extends HttpServlet {
#Override
public void init() throws ServletException {
super.init();
try {
Context ctx = new InitialContext();
TimerSessionRemote timerSession = (TimerSessionRemote) ctx.lookup("java:comp/env/TimerSessionRef");
timerSession.createTimer();
} catch (NamingException ex) {
logger.blah();
}