Jersey(2.10.4) Entity provider selection algorithm gives less priority to custom providers(MessageBodyWriter) making it not to be invoked - jersey-2.0

We have a custom MessageBodyWriter in our application that produces data of Media type application/xml.As we know Jersey 2.x has an algorithm(https://jersey.java.net/documentation/latest/message-body-workers.html#mbw.writer.selection.algorithm) that chooses a suitable MBR from a list of internal and custom MessageBodyWriters to persist entity into output buffer.The algorithm sorts MBR is based upon Object type distance and media type distance.So our Custom MBR is not getting invoked as we saw in the Jersey common code (MessageBodyFactory.getMessageBodyWriter())that our Custom Writer is at the below in the list and some other provider whose isWriteable() method returns true getting invoked.
The question is how can we force Jersey to invoke custom MessageBodyWriters ??Should we try adding a custom media type(like application/vnd.xml) to force it to call Custom types?

I was able to do this by setting jersey.config.workers.legacyOrdering to true in my web.xml file:
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
...
<init-param>
<param-name>jersey.config.workers.legacyOrdering</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
From the docs:
JAX-RS 2.0 is incompatible with JAX-RS 1.x in one step of the entity provider selection algorithm. JAX-RS 1.x defines sorting keys priorities in the Step 4 in exactly opposite order. So, in JAX-RS 1.x the keys are defined in the order: primary media type, secondary type declaration distance where custom providers have always precedence to internal providers. If you want to force Jersey to use the algorithm compatible with JAX-RS 1.x, setup the property (to ResourceConfig or return from Application from its getProperties method):
jersey.config.workers.legacyOrdering=true

Related

Does REST supports protocol buffers

This might be a very generic question, but considering the fact that REST is focused on accessing named resources through a single consistent interface; does it supports protocol buffers?
Yes, you can absolutely combine Protobuf and REST.
Protbuf specifies a way to encode data. REST specifies a way to interact with resources, but does not require any particular encoding for the resource bodies. If you create a RESTful HTTP-based API and use Protobuf to encode the entity-bodies (the technical term for the payload part of an HTTP request or response), then you are using both REST and Protobuf.
Back to the future, there is this Spring REST API with Protocol Buffers tutorial:
Generate the corresponding Java classes using:
protoc --java_out=java resources/baeldung.proto
Add the following dependency on your Maven's POM file:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0-beta-3</version>
</dependency>
Add the following converter to your #SpringBootApplication:
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
The ProtobufHttpMessageConverter bean is used to convert responses returned by #RequestMapping annotated methods to protocol buffer messages.
What's important here is that we're operating with Protocol Buffer specific data – not with standard POJOs.

What can be put in an EJB stereotype?

We're migrating an EJB 3.0 application to EJB 3.1 and would like to use #Stereotype to reduce some of the EJB configuration.
The annotations we plan to have are:
#Singleton
#ConcurrencyManagement(BEAN)
#PermitAll
#Interceptors or custom #InterceptorBinding annotation
#SecurityDomain("acme") JBoss / PicketLink
Of those I know that #Singleton can't be put into a #Stereotype and has to be on the EJB itself. What else can't be put into a #Stereotype?
Update
The specification [1], [2] says that
A stereotype encapsulates any combination of:
default scope, and
a set of interceptor bindings.
The examples then use Java EE 7 #Transactional which is an #InterceptorBinding which leads me to believe that none of the above annotations can be put into a stereotype.
The The Java EE 6 Tutorial states the following:
A stereotype is a kind of annotation, applied to a bean, that
incorporates other annotations. Stereotypes can be particularly useful
in large applications where you have a number of beans that perform
similar functions. A stereotype is a kind of annotation that specifies
the following:
A default scope
Zero or more interceptor bindings
Optionally, a #Named annotation, guaranteeing default EL naming
Optionally, an #Alternative annotation, specifying that all beans with this stereotype are alternatives
So as you saw yourself, the annotations you used are not in one of the mentioned groups.
My personal suggestion is, to be careful with creating and using stereotypes, since one then always have to know (or check) what it means, so for example I prefer using #Named #RequestScoped rather than #Model because saving one line of code does not make up to not see the scope at the first glance.

It possible in Resteasy to extract the URI mapping to an external, dedicated file?

It possible in Resteasy to extract the URI mapping to an external, dedicated file?
Annotating classes and methods is quick and easy but I would like to have a file that maps the URIs to functions. Something like:
/teams/{team}/player/{player-id} TeamResource.fetchPlayer
As far as I know this is not currently supported as part of the JAX-RS specification, but I could see you being able to do this with byte code insertion at runtime using something like javassist.
Basically you would add the #Path annotations to the your resource classes at runtime with the values loaded from your uri mapping file. Once the annotations were added to the resource you would then inject them into Resteasy.

difference between context-param and env-entry in web.xml

I know, env-entry uses jndi and can be changed during runtime, where context-param cannot.
However, I can inject the values of both via #Resource, where type conversion is made automatically.
What is the difference (pros/cons) of using context-param or env-entry in web.xml.

Change in scalatra filter behavior

I have multiple filters in my application, with one at the root.
<filter>
<filter-name>root</filter-name>
<filter-class>
my.own.classpath.RootFilter
</filter-class>
</filter>
<filter>
<filter-name>root</filter-name>
<filter-class>
my.own.classpath.SubFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>root</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sub</filter-name>
<url-pattern>/sub/*</url-pattern>
</filter-mapping>
In Scalatra 2.0.0 this worked fine. If RootFilter (which extends ScalatraFilter) had a binding for a url it would handle it, otherwise it would pass on to the other filters. However, in later versions of Scalatra it does not work the same. When I supply a url handled by SubFilter, the correct filter is still called, but the resulting text is not displayed. Instead, a blank page (with no HTML) is returned.
Is this a bug in Scalatra, or am I doing something wrong?
I'm not sure, Scalatra does not move at Java pace, so things change.
Here's an a snippet from the Scalatra Book v2.0 on ScalatraServlet vs. ScalatraFilter; there may be some clue here as to where the problem lies, particularly in regard to Not Found and ScalatraFilter delegating to the next filter in the chain (in your case, there is no next filter after sub)
The main difference is the default behavior when a route is not found.
A ScalatraFilter will delegate to the next filter or servlet in the
chain (as configured by web.xml), whereas a ScalatraServlet will
return a 404 response.
Another difference is that ScalatraFilter matches routes relative to
the WAR's context path. ScalatraServlet matches routes relative to the
servlet path. This allows you to mount multiple servlets under in
different namespaces in the same WAR.
Use ScalatraFilter if:
You are migrating a legacy application inside the same URL space
You want to serve static content from the WAR rather than a dedicated web server
Use ScalatraServlet if:
You want to match routes with a prefix deeper than the context path.