I'm trying to get rid of XML in my project.
I already tried to add this:
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setAddress("http://localhost:9000/");
sf.create();
to my Activator class, but my bundle wont start with this.
So, how usually people configuring endpoints?
(Sorry, no code, just some high level insights from my experience/projects)
I use jersey and its integration into the OSGi environment. I.e. org.glassfish.jersey.servlet.ServletContainer to which I register all jax-rs resources. This way, I can use whatever HTTP server implementation is available (for example, jetty) and configure it via the OSGi system environment properties.
For simplicity, I re-register annotated OSGi (declarative) services as singleton resources/endpoints into that ServletContainer.
Maybe, CXF has also a similar approach.
Related
is it possible to use a CXF ResourceComparator in OpenLiberty or WASLiberty?
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Customselectionbetweenmultipleresourcesoroperations
Must the cxf dependencies be supplied in the WEB-INF/lib or is enough to modify the apiVisibility of the app? And how can be declared to CXF? with a cxf.xml?
TIA
PacoG
There are multiple ways to use CXF in OpenLiberty/WebSphere Liberty:
* You can use the built-in jaxrs-2.0 feature, or
* You can package the CXF modules you need with your app (or in a shared library associated with your app)
If you use the first approach (jaxrs-2.0 feature), then you will only have the JAX-RS 2.0 APIs available - which does not include CXF ResourceComparators. There are a few IBM-specific APIs that go above and beyond the spec (for example, integration with CDI, security, attachment processing, etc.) - you can find more information on those APIs at:
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_dep_jaxrs.html
If you use the second approach, then you have the full feature set of the CXF modules in your application, but they will not be fully integrated with other Liberty features like the jaxrs-2.0 feature is. For usage instructions, I would suggest the Apache CXF documentation - like the page you referenced in the initial question.
Hope this helps, Andy
I've found conflicting answers to this question and I've failed to successfully run an example.
Can JAX-RS be implemented using Servlet 3.0 (in particular, Tomcat 7) with annotations, only, without having to implement another Servlet Container?
If no, please explain why the following quote from this book is either, incorrect or I'm interpreting it, wrong.
Because this example deploys within a Java EE application server or
standalone Servlet 3.x container, all we need is an empty web.xml
file. The server will detect that an Application class is within your
WAR and automatically deploy it. (RESTful Java with JAX-RS 2.0, Bill Burke)
To clarify what I don't need help with... I've, successfully, implemented JAX-RS in Tomcat 7 with Jersey using a web.xml, so, I don't need any explanation of how to do so. Also, I'm fully aware that other Java EE/Servlet Containers (TomEE, Glassfish, Jersey, Websphere, etc...) are all JAX-RS aware out of the box. I just need to know if I'm chasing my tail trying to get Tomcat 7 (Servlet 3.0) to work with JAX-RS without adding a Servlet Container and without web.xml entries.
In a Servlet environment, Jersey runs as a servlet or servlet filter. No way around that. So how does it work without declaring it in the web.xml? Two main components to this functionality
Programmatic registration of Servlet components (i.e. servlets and fitlers). You can do a Google search, and you should find some hits of examples.
Servlet pluggability introduced in Servlet 3.x. How it works is you implement a ServletContainerInitializer, list that implementation in a file named javax.servlet.ServletContainerInitializer, and put that file in the META-INF/services directory of the jar. The servlet container should scan jars looking for this file. When it finds on, it sees the implementation, finds the implementation, instantiates it, then calls it onStartup method.
Jersey has such an implementation of the SevletContainerInitializer in the JerseyServletContainerInitializer. This class is located in the jersey-container-servlet jar. So you need this jar for this to work. If you look at this method, this is where you will see the programmatic registration of the ServletContainer (the same one that yo would declare in the web.xml
But that's not all. We still need some way of configuring our application, at the least declare the servlet mapping. That's where the Application class and the #ApplicationPath annotation come in. We would extend the Application class and and annotate the #ApplicationPath("/path") where "path" is the same as the servlet mapping in the web.xml
#ApplicationPath("/api")
public class MyApplication extends Application {}
This is standard JAX-RS. With Jersey normally instead of an Application class, we use a ResourceConfig class (which is a subclass of Application)
#ApplicationPath("/api")
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("package.to.scan");
}
}
You can see more about Jersey deployment options in a Servlet 3.x environment, here.
It should also be noted, that a Java EE server has the JAX-RS implementation, so we only need to add the javaee-api jar to our application as provided dependency. But in a servlet container, we need to provide our own implementation, Jersey being such an implementation.
If you are using Maven, the main dependency you'll need is this one
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
This will pull a bunch of other jars in. You you aren't using Maven, then you can download all the jars here (the JAX-RS 2.0 RI bundle), and put all those into your application.
See Also:
How to use Jersey as JAX-RS implementation without web.xml?
I am using jax-rs for restful service. And I am trying to find out how I can use a contextlistener for webapp ? I am specifically using jax-rs 2.0 . Any suggestions on how to go about it , would be helpful. Thank you.
I'm not sure what linkage problem you have with servlet.jar. It should actually be in your classpath already, since JAX-RS uses it, too.
Also, if you use a framework such as Hibernate (or another JPA implementation for your MySQL database access), you may want to rely on the events that they trigger after insert/update/delete operations: see https://docs.jboss.org/hibernate/orm/4.0/manual/en-US/html/events.html for example.
Just my 2c.
This question is now up for Bounty! First answer that solves this problem wins.
So I've recently discovered that bundles in OSGI are not 100% isolated from each other, especially when your bundles share a common bundle that has a singleton in it, which can result in two unrelated bundles overwritting the singleton. This issue has manifested itself with the CXF libraries. Let me give a detailed example of what is happening:
We have bundle A, B and the shared bundle CXF all in a FuseESB ServiceMix (An osgi platform). CXF's Bus class is a singleton and because of how OSGI has a single classloader per bundle it will share this singleton with every other bundle that uses CXF. So I seem to be unable to create different buses for bundle A and bundle B, which is important that I do because bundle A should be using SSL and bundle B should not be using SSL. This is even more frustrating given that bundle A and bundle B have nothing to do with each other at all other than that they must be deployed together on the same ServiceMix.
Now I've been at this problem for a while now (1-2 months) and I've read up a lot of different solutions. The problem however is that a lot of the solutions require me to have complete control over the source code and in this case I do not. Bundle A that I'm creating is using some proprietary third-party non-osgi library, called Xenara, which uses CXF. For business reasons beyond my control I MUST use this third-party library. Fortunately I do have access to the CXF spring bean file that this library uses.
My guess for solving this problem is that I need to some how make it so that bundle A can use its own personal instance of CXF or at least make it instantiate its CXF Bus that isn't shared with other bundles. Here are the methods I've tried or considered:
I embedded CXF into bundle A but unfortunately the classloader kept fetching CXF from outside of bundle A instead of looking on the classpath. Never figured out how to force it to search for CXF in bundle A first before searching outside of bundle A.
Suggestions were made to make bundle A into a service. I think there were some misunderstandings and people thought that the singleton was in A and not in CXF. Regardless I tried it and it didn't solve the problem. The CXF bus was still shared between bundle A and B.
Override the classloading so that bundle A uses a different classloader for loading the CXF classes. I don't fully understand the logic for this but I'm sure it will be very tricky given that a spring bean is being used to create the CXF bus and http-conduit. See (4) below to get a better idea.
In CXF there is a way to set the CXF bus and http-conduit for a given thread context. I really want to use this solution, but I can't figure out how to translate the CXF bean file into equivalent java code. The CXF spring bean file is provided below. Note I don't have access to the source code using this http-conduit, which is why I haven't used examples show in this link here at "Using Java Code" because I don't have access to the SOAPService, the wsdl, etc...
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<cxf:bus>
<cxf:outInterceptors>
<bean class="com.xenara.messaging.security.IdentityAssertingOutInterceptor"
scope="singleton" />
</cxf:outInterceptors>
<cxf:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
</cxf:features>
</cxf:bus>
<http-conf:conduit name="*.http-conduit">
<http-conf:client AllowChunking="false" Connection="Keep-Alive" />
<http-conf:tlsClientParameters disableCNCheck="true" secureSocketProtocol="TLS">
<sec:keyManagers keyPassword="${javax.net.ssl.keyStorePassword}">
<sec:keyStore type="JKS" password="${javax.net.ssl.keyStorePassword}"
file="${javax.net.ssl.keyStore}" />
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="${javax.net.ssl.trustStorePassword}" file="${javax.net.ssl.trustStore}" />
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>SSL_RSA_WITH_3DES_EDE_CBC_SHA</sec:include>
...
</sec:cipherSuitesFilter>
</http-conf:tlsClientParameters>
</http-conf:conduit>
This sounds like the basic premisse of OSGi to me: isolation is provided, but you can do a lot of what you can in regular OSGi; such as, modify static members of a class, and since you all share that class (A presumably exports it, B and C import it), others will notice.
In most situations, I would advise you to not use static class state, since it is bound to mess something up for other bundles.
In your situation, it seems to me that bundle A is a library that has no real use being shared in the framework. I would package the library inside both of the using bundles, if you need real isolation, and not worry about the overhead too much.
For the record: this situation has nothing to do with Servicemix, it's basic Java: if we're talking about the same class, and someone changes a static property, others will notice. If this situation confuses you, you could read up a bit about the class loading and sharing mechanisms in OSGi.
The problem you are facing is fairly essential and basic. You have a static state in a supporting library CXF, while you still want shared instances of the libraries using CXF. You cannot modify the shared libraries (due to the sheer size), nor can you modify CXF (closed-source?). Let's call these shared libraries Foo and Bar.
Suppose you have the following classes:
CXF#1
Foo#1, using CXF#1
Bar#1, using CXF#1
WebApp#1, using Foo#1 and Bar#1
If I understand correctly, you now want another application to use the same instances of Foo and Bar, without using the same underlying library CXF#1. This amounts to the following situation.
CXF#2
CXF#1
Foo#1, using CXF#1 when called by App#1, using CXF#2 when called by App#2
Bar#1, using CXF#1 when called by App#1, using CXF#2 when called by App#2
WebApp#1, using Foo#1 and Bar#1
WebApp#2, using Foo#1 and Bar#1
This is just not possible; not in OSGi and not in any Java framework. An existing class cannot dynamically bind to another class, making the choice based on the calling Bundle. The only way to do this without modifying the libraries, is to duplicate the supporting libraries:
CXF#2
CXF#1
Foo#1, using CXF#1
Bar#1, using CXF#1
Foo#2, using CXF#2
Bar#2, using CXF#2
WebApp#1, using Foo#1 and Bar#1
WebApp#2, using Foo#2 and Bar#2
Indeed, this is a lot of effort and will explode the number of packages on disk and in memory. If the CXF package can only be used by a single application, the most logical solution is to duplicate the package and embed it everywhere you use it. Yes, this includes any and all libraries the package depends on.
A hacky/risky way to resolve this is as follows. You should be able to decompile the CXF class. This will allow you to modify the class as follows:
class CXF {
[...]
public static CXF getInstance() {
// based on the current Stack frame, determine which instance to return. Remember, the instance should be based on the WebApp bundle (while you still have shared libraries in between!)
}
}
This is not foolproof. Suppose your WebApp starts a callback thread originating from library A. This thread calls CXF.getInstance() -> The getInstance() method has no way of determining which WebApp started the callback thread.
The correct solution is to modify all libraries not to use the Singleton pattern. You can probably hack your way around the problem by implementing a special classloader, but this opens a whole other can of worms.
-- EDIT --
After reading up on CXF, it seems very strange that CXF exposes a Singleton class. The thing is made for OSGi! You are probably better off asking the question on the CXF mailing list; they will know all of the special sugar and reasons for making a singleton instance, and probably already thought about this usecase.
I have a sharp architecture project and I am making use of ApplicationServices in it as well.
There is requirement to provide a winform client that will use a wcf service. The wcf service will in turn use the ApplicationServices. I have not started working on the winform client yet but I am working on the wcf service.
Following the Northwind sample. I have created a "Wcf Service library" project and a "Wcf Service Application" project in my solution.
I am new to wcf but i know all the basics and have worked with web services alot in the past. I have following questions:-
1) I would like to know why there is a need of two projects, wcf library and wcf application?
2) I have noticed that the ITerritoriesWcfService interface in the Northwind sample inherits ICloseableAndAbortable.
public interface ITerritoriesWcfService : ICloseableAndAbortable
What is the purpose of ICloseableAndAbortable?
3) There is another class TerritoriesWcfServiceClient
public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService
What is the purpose of this class?
4) In the TerritoriesService.svc file, what is the purpose of Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" ? Usually in a normal wcf service application, I use codebehind attribute, but since the .cs file actually resides int the wcf service library project, I would like to know what following code is doing?
<%# ServiceHost Language="C#" Debug="true"
Service="Northwind.Wcf.TerritoriesWcfService"
Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %>
Even if I remove the above Factory attribute, I can still run the service app project and test the service using WcfTestClient utility.
6) When i run my service and using WcfTestClient If I run a method twice that accesses a repository, then on the second call, I get an ObjectDisposedException.
{"Session is closed!\r\nObject name: 'ISession'."}
I believe the NHibernate Session is getting disposed after the first call. How can reinitialise for each call or should I keep it open? I would like to know the best practice?
7) Also If I run the Northwind.Wcf.Web project and click on TerritoriesService.svc
file on the Directory Listing screen, I get the following error
{"Method 'Generate' in type 'Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator' from assembly 'Northwind.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator"}
I don't understand why is it throwing this error, when i already got the method and the Northwind.Web works fine too.
Awaiting
Nabeel
1) Strictly, you can combine the WCF library and the WCF application
in one assembly. This would mean that you would combine the contracts
and the implementations in one assembly.
If you are using svcutil.exe or Visual Studio (which uses svcutil.exe
in turn) to generate proxy classes for your client, you'd be fine
because the proxy classes are generated from discovery of your
services.
If however, you want to use your own classes for transport, which is
quite common in DTO scenarios and the like, you'd need to reference a
shared library from both the client and the server. If that shared
library would be your combined library/application assembly, the
client would get the application implementation in scope (because it
references the assembly that contains the contracts) and that's really
not something you'd want. The client needs to know as little as
possible about the server, just as much as the contracts expose --
that's what the contracts are for in the first place.
I think it is best practice to separate interfaces/contracts from
implementation anyway because it leads to better separation of
concerns. It's just that most parts of your solution don't need (and
shouldn't) know HOW something is done, just WHAT that something can
do. There are many more advantages over this, such as improved
testability.
2) Taken from the code documentation of ICloseableAndAbortable:
"When implemented by your WCF contracts, they are then interchangable
with WCF client proxies. This makes it simpler to use dependency
injection and to mock the WCF services without having to worry about
if it's a WCF client when you go to close/abort it.".
I think that says it all.
3) The client class is, like the code documentation says, a strongly
typed client proxy. It can be used by clients to talk to the server,
providing a strongly typed class that has members that correspond to
the service operations that can be called on the server.
The advantage of this class is that you don't need to use the
svcutil.exe generated proxy classes. This what they mean by not having
to configure it via WCF configuration. This allows you to ship proxy
classes to your clients so they can immediately talk to your server
instead of generating proxy classes first. It allows for more control
as well, changing the code that is generated by the proxy class is
really not something you'd want to do.
This again is a good reason to put the interfaces/contracts in a
separate assembly because you don't want to ship the service
implementation code to your clients.
4) The service host factory creates a service instance based on the
provided service type. This can come in handy if you want to put the
service code somewhere other than in the code behind file. You'd also
need it if you are using Depency Injection, you'd provide the service
contract interface as the type and the SharpArch.Wcf service host
factory resolves it to the correct implementation class type by means
of the DI framework (Castle Windsor in SA). You can think of this as a
means of getting hold of a service implementation while not caring
about where it actually is coming from.
In this case, the service will run when you remove the factory
attribute, because the default factory is able to resolve the service
type. You're bypassing on stuff like DI and session management though,
exactly that what makes SA valueable.
5) I'll have to skip this one because apparently there is no question number 5 :-)
6) As in the Northwind sample project, you are probably using the ServiceHostFactory that comes with SA. With this service host factory, each created service instance is extended by a behavior that closes the NHibernate session directly after it's called. That okay by itself but chances are that your proxy clients are not managed in a transient way by Castle Windsor. Therefore instances get reused, including the closed sessions they (still) contain. Decorate your client proxy classes with the Transient attribute (Castle.Core.TransientAttribute) and Castle Windsor will create a fresh instance every time a service call is performed.
Apparently, there is a second way to solve this but it requires modification of the S#arpArchitecture code base. See WCF connections which process more than one request fail because the nhibernate session is closed and isn't re-opened. on GitHub.
7) I'm sorry, I seriously have no idea. I might look into this later.