eclipse / lyo

Eclipse Lyo, a Java SDK for OSLC-based tool integration

Home Page:https://oslc.github.io/developing-oslc-applications/eclipse_lyo/eclipse-lyo.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Oslc Xml Provider always kicks in for application/xml

benjaminr-ps opened this issue · comments

The Olsc Xml Provider is not usable in a mixed setup, with simple JAXB Provider, since it is now always tried to read as RDF/XML.

Can you please fix this issue?
We try to upgrade from previous version of Eclipse Lyo.

I can't upgrade to 5, since this is already build with Java 11.

Hello Benjamin,

Are you asking us to apply this fix? #228

Also, please specify which version do you need fixed? From the link you gave, it looks like 4.1.0.

Regarding the fix itself, we need to be quite careful, because this is the place where any change could be breaking if someone relied on it (cf. https://www.hyrumslaw.com/). I think that the actual problem is not in the isReadable method but on the JenaProvidersRegistry. There, classes that bind to application/xml (not application/rdf+xml) are added:

https://github.com/eclipse/lyo/blob/master/core/oslc4j-jena-provider/src/main/java/org/eclipse/lyo/oslc4j/provider/jena/JenaProvidersRegistry.java#L29-L31

You should be able to work around it in your application by registering your providers like this:

        RESOURCE_CLASSES.addAll(JenaProvidersRegistry.getProviders());
        RESOURCE_CLASSES.remove(OslcXmlArrayProvider.class);
        RESOURCE_CLASSES.remove(OslcXmlCollectionProvider.class);
        RESOURCE_CLASSES.remove(OslcXmlProvider.class);

PS. We already made changes/tests to the isReadable/isWritable methods in these two PRs:

  1. #286
  2. #288

@jadelkhoury I would also like to remove these providers either from JenaProvidersRegistry.getProviders() in Lyo 6 or add a JenaProvidersRegistry.getProvidersModern() sans these bad providers or have Lyo Designer generate the code either to call JenaProvidersRegistry.getProvidersModern() or apply the workaround I listed above.

We should also deprecate OslcXmlProvider, OslcXmlArrayProvider, OslcXmlCollectionProvider and encourage RDF/XML only to be parsed by OslcRdfXmlProvider and friends.

Hey, thanks for the fast & detailed reply.

I admit I did not try to understand your PRs fully.

Currently, I am not interested in any future versions of Eclipse Lyo.

Returning true is the only problem, which seems to be changed from version 2.4 to 4.x, which is a breaking change already.
I would even go further and say it's a bug, since I do not see any evidence doing so.

Now, I have circumvented the situation, defining my own provider which inherits the OslcRdfXmlProvider and checks with old behaviour.
(Let's see how far I get with this. ;))

Hi @benjaminr-ps

Somewhere in your code (I guess an Application class that extends javax.ws.rs.core.Application), you are calling JenaProvidersRegistry.getProviders() which actually returns all OSLC providers, including the ones that you do not desire to register.

So instead of calling JenaProvidersRegistry.getProviders(), why not simply pick the providers you want to add? See the implementation of that method to get a more exact list of providers to pick from.
Alternatively, as suggested by @berezovskyi follow the call, but some calls to remove the undesired ones.

I believe this would be a more stable solution. Calling JenaProvidersRegistry.getProviders() is simply a convenience method to register all providers, but this is not your case, so why register them in the first place?

@jadelkhoury I would also like to remove these providers either from JenaProvidersRegistry.getProviders() in Lyo 6 or add a JenaProvidersRegistry.getProvidersModern() sans these bad providers or have Lyo Designer generate the code either to call JenaProvidersRegistry.getProvidersModern() or apply the workaround I listed above.

@berezovskyi are there "bad" providers, or are some simply not desired in certain scenarios.
Ideally, the method would have been called the more accurate getAllProviders instead.
In LyoDesigner, we can simply add a user code block that explains the setup, plus gives the user the option to remove certain ones.

Currently, I am not interested in any future versions of Eclipse Lyo.

@benjaminr-ps It's fine, we are only asking you to clearly state the version you are using right now.

Returning true is the only problem, which seems to be changed from version 2.4 to 4.x, which is a breaking change already. I would even go further and say it's a bug, since I do not see any evidence doing so.

The reason to reduce the checks was to allow instances of different resources to be de/serialized, see eclipse/lyo.core#21. Setting it to true was a mistake, but not because of the issue you described but because non-collection providers could sometimes trigger on collections. And given that's a breaking change, that's exactly why it was postponed from being released in 2.4.0 and instead delivered in 4.0.0.

Now, I have circumvented the situation, defining my own provider which inherits the OslcRdfXmlProvider and checks with old behaviour.

Could you please confirm that the JAXB Provider is supposed to read application/xml and that the application/xml gets passed to OslcRdfXmlProvider that is configured with @Consumes(value="application/rdf+xml")? You can do this by checking the value of the mediaType in isReadable.

To be clear, this should never happen. We've had a small number of such reports over the years but I was never able to reproduce with Jersey to trigger a provider on a MIME type it didn't declare. Please confirm you are using Jersey (<= 2.29.1 if you are on Lyo 4.x, iirc), package as WAR and run it using Tomcat or Jetty in a non-embedded more? These are the environments we regularly test. And please confirm Jersey is calling OslcRdfXmlProvider.isReadable when you POST some application/xml content, not OslcXmlProvider.isReadable.

I tested RESOURCE_CLASSES.remove(OslcXmlProvider.class) on the https://github.com/oslc-op/refimpl/tree/21c41f22e02c4fe6ec23ae30ecda428fc1afbca1 (using Lyo 4.1.0.RC) and it stopped the API from accepting application/xml perfectly. If you can modify the reference implementation at that version to trigger the bug, we can discuss a bugfix release. See my test under oslc-op/refimpl@91b92c6

PS:

I can't upgrade to 5, since this is already build with Java 11.

We are trying to stay as low as possible with the JDK requirement, we understand the needs of integration library users. But our upstream dependencies are making our life hard, esp. Jena, which we can't replace. They already declared a plan to drop JDK 11 support shortly after JDK 21 is released in 2023-09 and only support JDK 17 and JDK 21. Spring framework, Jakarta EE, and many other projects seem to be following the "2 last LTS" policy as well.

Right now the policy of Lyo is to stay on the lowest JDK version possible, using oldest possible Jena versions without CVEs. But when a CVE is filed on Jena, we must upgrade due to security concerns and this sometimes brings a JDK dependency increase.

This is how things will remain to be unless we get enough financial support to keep forks of older Jena versions and backport CVE patches to them.

are there "bad" providers, or are some simply not desired in certain scenarios.

@Jad-el-khoury, the https://www.w3.org/TR/rdf-syntax-grammar/#section-MIME-Type spec defines "The Internet media type / MIME type for RDF/XML is application/rdf+xml — RFC 3023 [RFC3023], section 8.18.". Parsing or sending RDF/XML using application/xml MIME type is a violation of the standard, thus we should move those providers to getLegacyProviders() and @Deprecate them.

Thanks for your detailed thoughts.

My current setup looks as follows:

  • Jersey 2.37
  • Lyo 4.1.0

I noticed, that OslcRdfXmlProvider.isReadable is getting called, since being defined first by Jersey, and JAXB is not called.

Not sure, if there is any response with content-type "application/xml", but actually having the content with RDF/XML, returned by our supported 3rd party tools (like IBM's ELM).

(unfortunately anything can be possible in real world ;))

I noticed, that OslcRdfXmlProvider.isReadable is getting called, since being defined first by Jersey, and JAXB is not called.

It will only get called if the request comes with application/rdf+xml MIME type. My JAXB example oslc-op/refimpl@91b92c6 allows JAXB to process application/xml and Lyo to process application/rdf+xml perfectly at the same time.

ELM is quite likely to return application/rdf+xml and in this case it's completely right that OslcRdfXmlProvider would get to handle that. If you want OslcRdfXmlProvider to handle only some application/rdf+xml payloads and want JAXB to handle the rest of application/rdf+xml payloads, I think the subclassing you went with is the right way to go.

@benjaminr-ps I will close the issue. Please reopen if you can reproduce your issue on top of my JAXB example: oslc-op/refimpl@91b92c6