Jersey slow between RESOURCE_METHOD_START and real invoke() - spring

Java : 8
Jersey : 2.35
Spring : 5.1.5.RELEASE
com.google.appengine.tools : 0.8.2
Jersey doc : https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/user-guide.html
Jersey code source : https://github.com/eclipse-ee4j/jersey/tree/2.35
On my production server, first call of my REST API took a while.
After a lot of research, it seems that something happen in Jersey at ResourceMethodInvoker class.
The ResourceMethodInvoker class in method invoke calls context.triggerEvent(RequestEvent.Type.RESOURCE_METHOD_START);
then this.dispatcher.dispatch(resource, context.request());
and finally, calls AbstractJavaResourceMethodDispatcher.invoke() which create invokeMethodAction
For some reason, the first call in production can take 2 seconde between the triggerEvent and invokeMethodAction
What happen ? Is it normal ?
Any idea ?
Thanks.

Related

Spring Boot 2 controller returns a callable but http response remains empty

I'm in the process of migrating a Spring Boot 1.5 project to Spring Boot 2.1.8 (JDK 1.8, Kotlin 1.3.50).
I have a few controllers whose methods look like:
#PostMapping("post")
fun post(#RequestBody input: String): Callable<JsonNode> {
return Callable {
requestAsJson(input)
}
}
This works well in Spring Boot 1.5, without any further configuration. However with Spring Boot 2.1.8, the call does not fail but the HTTP response remains empty.
When I use start.spring.io to generate a minimalistic example, it works fine, so I guess that there is something wrong in my configuration.
When I enable debug traces for the Spring MVC, the final trace I get is:
[nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [{"data":{"...
[nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Exiting from "ASYNC" dispatch, status 200
So this looks fine to me, but still no response is received (using Curl or Postman to test).
I'm a bit at a loss now, since it was working like a charm in Spring Boot 1.5 and I'm trying to get a hint on how to get out of this issue.
Thanks for any help,
Damien
I had declared a ShallowEtagHeaderFilter bean the following way in my WebMvcConfigurer:
#Bean
fun shallowEtagHeaderFilter(): ShallowEtagHeaderFilter {
return ShallowEtagHeaderFilter()
}
While this was working fine in Spring Boot 1.5, this causes the controller async methods (returning a Callable) to not return any content any longer. Removing this bean for Spring Boot 2.1 restores a normal behavior.
I still need to seek a way to have my e-tag, but for now, this solves the present issue.

Spring Integration RedisLockRegistry example

I want to use Spring Integration RedisLockRegistry . I have some questions about Spring Integration RedisLockRegistry.
Can I use the redisLockRegistry as a Spring bean ? it means my application just a single redisLockRegistry.
I see the RedisLockRegistry implement ExpirableLockRegistry in the version 5.0,
Should I need run the expireUnusedOlderThan method?
I met the same questions and start analyze spring code. So from sources I can state that:
Yes you can create and configure it as a bean of any instance of LockRegistry like RedisLockRegistry, JdbcLockRegistry. For test purposes I'd like even use PassThruLockRegistry
I tried to find any invocation of expireUnusedOlderThan inside Spring without success.
So I have created simple scheduler as following:
#Autowired
private ExpirableLockRegistry lockRegistry;
#Scheduled(fixedDelay=50000)
public void cleanObsolete(){
lockRegistry.expireUnusedOlderThan(50000);
}

Jersey Exception Java 1.8

I am calling a REST service and the provider has supplied a client. Client's specification is to use Jersey 2.18. So i have used the below jersey dependencies
Jersey-client-2.18.jar
Jersey-common-2.18.jar
Jersey-entity-filtering-2.18.jar
Jersey-guava-2.18.jar
jersey-media-json-jackson-2.18.jar
I am making calls using scheduledThreadPoolExecutor and my application is running in tc server and JDK 1.8. Sporadically i get the below exception. I tried searching this exception in google but no luck. But i see the below for almost everytime
Cannot create new registration for component type class > org.glassfish.jersey.client.authentication.HttpAuthenticationFeature
Exception
java.lang.NullPointerException at
org.glassfish.jersey.model.internal.CommonConfig.configureFeatures(CommonConfig.java:694)
at
org.glassfish.jersey.model.internal.CommonConfig.configureMetaProviders(CommonConfig.java:644)
at
org.glassfish.jersey.client.ClientConfig$State.configureMetaProviders(ClientConfig.java:365)
at
org.glassfish.jersey.client.ClientConfig$State.initRuntime(ClientConfig.java:398)
at
org.glassfish.jersey.client.ClientConfig$State.access$000(ClientConfig.java:88)
at
org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:120)
at
org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:117)
at
org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:340)
at
org.glassfish.jersey.client.ClientConfig.getRuntime(ClientConfig.java:726)
at
org.glassfish.jersey.client.ClientRequest.getConfiguration(ClientRequest.java:285)
at
org.glassfish.jersey.client.JerseyInvocation.validateHttpMethodAndEntity(JerseyInvocation.java:126)
at
org.glassfish.jersey.client.JerseyInvocation.(JerseyInvocation.java:98)
at
org.glassfish.jersey.client.JerseyInvocation.(JerseyInvocation.java:91)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:307)
I resolved this issue. My implementation was wrong. The client object was defined as a class level variable and it was initialized during every method call. During parallel call. every thread concurrent call attacks the same class level object and tries to modify and hence the object was not properly initialized. Now i fixed it by injecting the class from spring so that it is not modified during every call.

Spring MVC 4 REST with protocol buffers not working

I am trying to use Spring MVC 4's Rest templates to support google protocol buffers as message format. I have am following this post on Spring framework blog
spring-mvc-google-protocol-buffers
I checked out the sourceCode trying to implement it in my environment.
I have two issues- I cannot get it to compile when I turn Java.version to 1.6 and i cannot get it to work as a webapp (don't know what
will be the context-root of the converted war file)
-Details-
I have a requirement to make this code work as a web-app and deploy on java6 container (weblogic 10.3.6 -servlet 2.5 compliant)
So i changed the java 8 features from the codebase to make it Java 6 compatible.
The only problem is when I change the pom.xml's following section
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.DemoApplication</start-class>
<java.version>1.8</java.version>
</properties>
to change the java.version to 1.6 value, then try to do mvn clean install , the DemoApplicationTests class fails to compile with this error.
-google-protocol-buffers-master\src\test\java\demo\DemoApplicationTests.java:28: cannot find symbol
[ERROR] symbol : constructor RestTemplate(java.util.List<org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter>) is not defined
[ERROR] location: class org.springframework.web.client.RestTemplate
The following link shows that Spring codebase normally doesn't have any Java 8 specific source code so not sure why this code only compiles in Java 8
https://spring.io/blog/2015/04/03/how-spring-achieves-compatibility-with-java-6-7-and-8
--------------------------------------------------------------------------------
The following link shows how to convert a spring boot application to a WAR app.
I did change the pom.xml packaging option to war.
The code gets build by mvn clean install without issues and the .war file gets generated.
But there's no web.xml - so i cannot tell what will be the context-root of the deployed web app.
I either way deployed the webapp on weblogic 10.3.6 ( which is java 6 compatible)
and it deployed fine.
But when I run the DemoApplicationTests (that I have changed to point straight to the URL
using this call (got the context-root from the weblogic console by clicking on the deployed web app)
ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
"http://127.0.0.1:7001/demo-0.0.1-SNAPSHOT/customers/2", CustomerProtos.Customer.class);
I keep getting 404 not found error.
I have put up my changed code here.
https://github.com/robinbajaj123/spring-and-google-protocol-buffers
Your feedback will be appreciated.
You'd need to convert the Spring Boot app to also be a valid Servlet application. If you were using Servlet 3 or later and chose a .war-based deployment from start.spring.io you'd get a ServletIntializer which is a Java class that is the programmatic equivalent of web.xml. Since you're using 2.5, not 3.0, you need an explicit web.xml. You might check out this sample on how to get a Boot app hoisted up in a Servlet 2.5 environment, though using Servlet 2.5 is not recommended!. It's worth mentioning that Servlet 3.0 support was introduced in 2009..
Finally, this code uses Java 8 lambdas. You'll need to replace the lambdas with Java 6-equivalent code. One example I see is:
#Bean
CustomerRepository customerRepository() {
...
The last line in the #Bean definition returns a lambda: customers::get. Replace it with:
final Map<Integer, CustomerProtos.Customer> customers =
new ConcurrentHashMap<Integer, CustomerProtos.Customer>();
return new CustomerRepository() {
public CustomerProtos.Customer findById(int id) {
return customers.get( id) ;
}
};
Similarly, replace the forEach method in the List w/ an old-school for-in loop:
for (CustomerProtos.Customer c : Arrays.asList( ... )) {
customers.put(c.getId(), c);
}

Spring mvc interceptor Basics

I am new to Spring and currently working on a spring application.
I am very confused regarding the spring interceptor and Interceptor in Spring security.
I have below doubts.
1. What is the use of Interceptor ? Is it used to modify the requested url or to validate the url ?
2. Is it possible that through interceptor i can modify my url /Test/MyTest to /Test/Intercept/MyTest ?
3. If Interceptor is only used to vaidate the url then only by url-pattern=/"somevalue" it will work or need to implement Interceptorhandler ?
Please help me out to understand these basic functionalities of interceptor.
I went through lot of sites but still not clear about all these concepts.
An interceptor is somewhat like a filter. A filter processes the request and response around a servlet and an interceptor processes the request and optionally the model around a spring controller. Common uses are pre-processing a request to ensure that a condition is realized (preHandle), or populating the model with attributes common to different controller methods (postHandle). afterCompletion is mainly used to perform cleanup at the end of request processing.
Actually interceptor can do three things
preHandle(…) – called just before the action
postHandle(…) – called immediately after the action
afterCompletion(…) – called just before sending response to view
Best example of prehandle is-checking whether the user is logged in or not.
Hope you have got some idea of interceptor
Spring MVC Interceptor is similar to Servlet Fiter Concept. Spring MVC provides ability to define set of classes called interceptor which will be called before and after a request being served. Interceptor will implement HandlerInterceptor which following thee methods need to be implemented:
preHandle() : Called before the handler execution
postHandle() : Called after the handler execution
afterCompletion() : Called after the complete request has finished
There is a good tutorial by MKYONG which I recommend you to have a look at it that I found it helpful in understanding the fundamental concept of interceptor. Hope that helps to get you started.

Resources