Closed hohwille closed 10 years ago
If we use metro from jdk we still need to use another implementation for JAX-RS (e.g. restEasy). CXF would give us one solution for implementation of both standards. It integrates also very good with Spring and other frameworks, like Camel (it would be helpful if one needs to use Camel). Could you attach a patch with your poc or commit the changes into a new branch, e.g. cxf-poc
?
If we use the jdk metro version we should check whether the JAX-WS RI’s Spring support works (using the JAX-WS Commons Spring integration). Another way would be export using the SimpleJaxWsServiceExporter
Another disadvantage of the Metro provided by jdk is locking to the version provided by the used jdk. We should probably think about integrating the JAX-WS RI provided by external jars. We were using for a short time the jdk version of Metro and it made a lot of compatibility problems when we wanted to implement more complicated extensions (like handlers or even tubes) and run in development using the version provided by jdk and in production using the version provided by WebLogic. We have migrated to the external JAX-WS RI implementations (locally in classpath, in prod included in ear file) and it works with no problem.
But for easy cases it should make no problems. We can eventually provide one concept for Metro (and something for JAX-RS) and another for CXF.
We're both using JAX RS and JAX WS in our project. I think have to check which implementation and version were using exactly. I can provide some example snippets of what were doing then.
Which JAX-RS implementation are you using?
I thinks it's metro (for jax ws) and jersey (for jax rs), but I have to check.
I thinks it's metro (for jax ws) and jersey (for jax rs)
Okay that makes sense.
CXF would give us one solution for implementation of both standards.
Yes, that would be nice because you often have to deal with both and then you only have one solution to hook up with authentication, etc.
Could you attach a patch with your poc or commit the changes into a new branch
I comitted the change on the master. If we go for metro and jersey, I will simply replace it. Currently anything is better than nothing. The REST service is not working as expected. Might be some config missing... Any CXF experienced person might have a look. Apart from that the pure PoC is as expected. The code only uses CDI and JAX-WS/JAX-RS but has no other proprietary dependency. This is the way it should be. For our simple application the impl should be exchangeable just by chaning the config (maven dependencies and spring XML),
Have you pushed the commit? I can't see it
Have you pushed the commit? I can't see it
Sorry, I was to tired. Now pushed...
Thanks. What a problem is with the REST service? Could you open an issue in oasp4j-sample? I'll look at it next week.
In put from Frank:
JAX-WS (Metro) is part of JDK 1.7. We use it with Spring and it works seamless. For JAX-RS there is no implementation in JDK 1.7. The reference implementation is Jersey. We also use it with Spring and it works seamless.
Sounds great so far. However Martin G. wrote:
For versions before JDK 1.7 it gets unpredictable because of endorsed libs and different versions of JAX-WS. With WebSphere 8.0 we just had trouble with webservices that have been traced back to an old and broken version of JAX-WS from IBM.
Mhm. This underlines what @sobkowiak said. Relying on something build into JDK or Appserver is sometimes tedious. However both approaches have their pros and cons. Considerations for Java < 1.7 are IMHO not relevant. However the same problems may apply in the future with upcoming versions. But as we are going to promote the actual standard and use it in the code, "only" the integration and configuration will change if you have to switch. Having less dependencies and using what java already provides is at least a Pro argument according to KISS.
Even with Java 7 we had problems with running the application on WebLogic 12c. We have solved it by using the external JAX-WS implementation. We had to make additional configuration in ears to force WebLogic to use the implementation provided by ears (instead of the WebLogic implementation)
But as long as the application will run on as separate jdk process or will be started using web container (which does not provide JAX-WS implementation) the jdk version should work.
We can provide solution for the problem with starting the application on WebLogic. Perhaps can Martin provide a solution for WebSphere (if they have solved the problem)
I think, we should also test it with JBoss AS/WildFly. It uses CXF as internal JAX-WS implementation.
Where should we collect such informations? In Wiki too?
Thanks. What a problem is with the REST service? Could you open an issue in oasp4j-sample? I'll look at it next week.
It is available but does not respond. And this is just a HelloWorld example. I am sure that there will be an easy fix so nothing against CXF except maybe that it might have a pitfall I ran into (HelloWorld should actually run OOTB without magic configuration triggers). The services get listed here and you can see them if you start the app: http://localhost:8080/oasp4j-example-application/services/ IMHO the following URL http://localhost:8080/oasp4j-example-application/services/rest/HelloWorld/sayHi/world/ should print "Hello world" but it does returns 200 with empty payload. In case we gonna drop CXF then I would not investigate more but for CXF users it would of course be interesting to find a solution. For rest we need a PoC at least for
Cyclic references, advanced Polymorphism, etc. should be considered as an anit-pattern for WS and REST services and are out of scope. This is only acceptable for internal Java to Java communication that we will do via HttpInvoker.
I fixed the PoC with CXF (already pushed). It now works properly. Only the service overview page is confusing for REST services. I fixed the spring config (and removed "helloWorld" from address that was also present in Path annotation causing a duplication for URL - so a mistake from my end). For the moment we already have a foundation to build the services for the example. We can simply replace the implementation used under the hood. At least as "addon" or documentation hint we could leave the CXF config for those that want to use it in case we switch to metro+jersey.
Independent from the implementation and technology what are the conventions and best practices? I already established as global "services/" path and then divided into "ws/" and "rest/". On the next level should there be the <component> and then the actual service? services/rest/tablemanagement/freeTables or services/rest/tablemanagement/TableManagement/freeTables (this one is not DRY). Should we relate this to the package convention? Then we should use "service" instead of "services" and maybe <component> before "ws" or "rest". Might not matter that much but should be clarified, defined and documented.
We can provide solution for the problem with starting the application on WebLogic. ... I think, we should also test it with JBoss AS/WildFly. It uses CXF as internal JAX-WS implementation. Where should we collect such informations? In Wiki too?
- We promote to use the standard. The example application promotes what we recommend if there are no operational or other demands and requirements. If someone is using WildFly because this is a demand there is no reason why he must use Metro and Jersey inside WildFly.
- For the documentation and example we want to follow KISS and that means we describe ONE solution that we recommend and that is proven to work (See architecture wiki page).
- IMHO we could have extra wiki pages that collect the hints for such purpose. We will come up with a simple convention for this and add it to the wiki authors guide. This way the extra hints do not get in the way but are available for those who search for them due to advanced demands.
Things are never smooth and easy :( CXF uses jettison for JSON support and this is anything but KISS: http://stackoverflow.com/questions/6312030/cxf-no-message-body-writer-found-for-class-automatically-mapping-non-simple-r http://cxf.apache.org/docs/jax-rs-data-bindings.html
By default, Jettison wrongly serializes List objects containing a single value only. To work around this issue, one needs to enable a 'serializeAsArray' feature on a JSONProvider, with the additional option of specifying the individual fields which needs to be processed accordingly using an 'arrayKeys' property. Please see this example for more information.
If this is the official documentation then the decision is easy: We will use Jersey as proposed by @maihacke, Frank and Martin. See the ease of use here: http://examples.javacodegeeks.com/enterprise-java/rest/jersey/json-example-with-jersey-jackson/
Together with @agreul I changed the PoC to jersey (already pushed, not visible in this issue as the sample is in a separate repository). As always some tricky parts to get along but now it works as expected. POJOs get down to JSON seamlessly. The Web-Service has to be ported with metro what we will do on monday. Also we will start with writing real REST services for the angular client and remove the HelloWorld PoC. I also tagged the PoC running CXF and pushed the tag in case we need that later on. For the rest services we have to address these aspects:
Then we should have an easy to use and smooth solution and can start the documentation.
We will come up with a simple convention for this and add it to the wiki authors guide.
What do you exactly mean with the wiki authors guide?
CXF uses jettison for JSON support and this is anything but KISS:
We don't need to use jettison with CXF. Please look at http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Jackson. Together with schema based Spring configuration it's KISS too.
I know, it's decided to use Metro and Jersey as a standard for OASP4J, but I think, we should provide the CXF guide as alternative for Metro and Jersey for projects which prefer this solution (it can be also provided somewhere in optional documentation if you prefer to promote one standard).
Let's implement a solid standard solution with Metro and Jersey. I'd like to take over the CXF theme next, after the more important themes are finalized.
A few comments from my side: 1) In my project we are using Jackson for Java <-> JSON and it works great. 2) In general sticking to JDK is something we should avoid, because time-to-application-server is too long. 3) Writing any code ("On Monday I will create a solution...") should automatically raise a question if there is no a simpler solution...
What do you exactly mean with the wiki authors guide?
1) In my project we are using Jackson for Java <-> JSON and it works great.
This is what we are using with Jersey.
2) In general sticking to JDK is something we should avoid, because time-to-application-server is too long.
I see your point. But for Metro it is about JDK1.7 and that is what we already require as minimum by our code (will not work in JDK1.6 already). I think CXF is a great escape if you have pain with Metro and JDK version. But Metro2 and Jersey have been used by many projects in larger scale and it works with their requirements. This is a major aspect. Which project is already using CXF 3 in mission critical situations? Maybe we have one but I did not find anybody in my near circles...
3) Writing any code ("On Monday I will create a solution...") should automatically raise a question if there is no a simpler solution...
I solved this in less than 2 Minutes. We had a long weekend in Germany. Let us not discuss on such aspects. I sometimes want to give a preview when someone can expect progress. That has nothing to do with the complexity of the solution just with my personal schedule.
This is what we are using with Jersey.
Using Jersey and Metro we have to use 2 different implementations and 2 different ways for configuration. Using CXF you can simply use the Spring xml scheme for both service types - I think, this is less confusing for developers
Using Jersey and Metro we have to use 2 different implementations and 2 different ways for configuration. Using CXF you can simply use the Spring xml scheme for both service types - I think, this is less confusing for developers
IMHO this is not really the point. With CXF you already have 2 ways to configure REST and WS as these are two different animals. For JAXRS you configure a "server" and declare all service endpoints in that service and for JAXWS you define endpoints individually. In any way I did not want to use any of such approach and instead just use a marker interface so that all services implementing the marker and available as spring bean are auto registered. I solved this for Jersey and will try to find a similar solution for CXF.
I currently gave CXF another try because the spring integration is buggy: https://java.net/jira/browse/JERSEY-2112
JSON with Jaxkson is working easy in CXF. Still I am looking for a large-scale project that has proven success with CXF before promoting it.
There are some more issue addressing this point:
https://java.net/jira/browse/JERSEY-2301 https://java.net/jira/browse/JERSEY-2187
Spring Integration is relatively new (Mid 2013) https://java.net/jira/browse/HK2-40 https://java.net/jira/browse/JERSEY-750
For the record: We decided for CXF as JAX-RS implementation and everything is working fine in our sample application. Currently we also use CXF for JAX-WS but I opened issue #29 for final clarification. Therefore I will close this issue as it is very generic and we have other more specific issues now for all remaining problems and tasks.
We need a service framework. It should ideally support both JAX-WS and JAX-RS and integrate with CDI and spring. I managed to do this with CXF in our example (not committed). Simon says this also works with metro from JDK OOTB. In that case this would be preferred.