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.
Does it exist a way to test the web.xml with JUnit in a Spring MVC application?
I have a "web" folder at the root of my project. It contains a WEB-INF/web.xml file.
I write unit test like this:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("web")
#ContextConfiguration("path/to/mySpringApplicationContext.xml")
public class MyClassTest() extends AbstractMyClass {
//...
#Test
public void testController(){
mockMvc.perform(get("/path/to/myControllerURL"));
}
}
The web.xml is not read. I'm sure of that because when I do a syntax error in the web.xml file, the test still works.
Note: I could use an embedded Tomcat server to test the web.xml but I don't know if it exists a more simple way to test this file without an embedded server.
You're doing integration test of our code with spring framework. It does not include the java web container (usually tomcat or jetty), which are the ones concerned with web.xml. Please look at functionnal testing and tools like embedded jetty and selenium (these are not the only existing solutions).
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.
It's clear to me how to inject an object which is in my domain (I have access to the source) using Weld. You just annotate the implementation with e.g. #Named and #ApplicationScoped, and then annotate the target attribute with #Inject to get the implementation injected.
However, not sure how can I inject implementations of classes which I don't have access to its source code. For example, I am using Dozer. Dozer mapper is programmed against an interface (Mapper) and I want Weld to inject the implementation (DozerBeanMapper), but since I don't have access to the source cause I am using a .jar dependency, I cannot annotate it.
Any ideas on how to achieve this?
Annotations embedded within POJOs is the internal configuration. Internal configuration and 3rd party components don't mix. External configuration(such as beans.xml) is the only way. You should check the document of Weld for external configuration.
I am using an embedded version of jetty 7 to load a web application using Apache MyFaces 1.2 in a junit 4 test class on the advice from another thread.
While running the test i get this error.
java.lang.IllegalStateException: No Factories configured for this Application. This happens if the faces-initialization does not work at all - make sure that you properly include all configuration settings necessary for a basic faces application and that all the necessary libs are included. Also check the logging output of your web application and your container for any exceptions!
If you did that and find nothing, the mistake might be due to the fact that you use some special web-containers which do not support registering context-listeners via TLD files and a context listener is not setup in your web.xml.
A typical config looks like this;
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
This application works fine with tomcat, weblogic and even oc4j!
How can i get this to work with jetty?
I solved this by adding the myfaces-impl jar which had the .tld file inside the WEB-INF/lib directory.