Multiple CXF bundles in OSGI binding to same address - spring

I have multiple WARs that expose CXF JAXRS endpoints. They have similar web.xml
<web-app id="app1">
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>app1</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>app1</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
They share common Spring configuration (named common-rest.xml)
<beans>
<import resource="classpath:META-INF/cxf/cxf.xml" />
<context:annotation-config />
<bean id="httpDestinationRegistry"
class="org.apache.cxf.transport.http.DestinationRegistryImpl" />
<bean id="baseJaxRSServer"
abstract="true"
lazy-init="false"
class="org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean"
init-method="create"
p:address="${http.server}/" />
</beans>
And every bean has similar configuration
<beans>
<import resource="classpath:META-INF/app/common-rest.xml" />
<bean id="app1JaxRSServer"
parent="baseJaxRSServer"
p:serviceBeans-ref="app1ServiceBeans" />
</beans>
Exact path is defined in each bundle's MANIFEST
Web-ContextPath: app1
The problem is I can't make multiple bundles work together. With single bundle it's working OK, but if I try to run another one I get exception for creating app1JaxRSServer bean
org.apache.cxf.service.factory.ServiceConstructionException: There is an endpoint already running on /.
Using Karaf 4.0.9, CXF 3.1.13, Spring 3.2.18

The reason is
<url-pattern>/*</url-pattern>
If you have multiple bundles with this settings their endpoints will clash.
Try to use different prefixes per bundle.

I've found the solution, there was a problem with DestionationRegistry which was created by default by CXF HTTP Transport OSGI Bundle (the one that registered default /cxf/* endpoint). I had to disable this bundle by setting
org.apache.cxf.osgi.http.transport.disable = true
in Karaf properties

Related

Apache CXF and Spring but no WSDL (recursive links)

I have written a small sample web service, using Apache CXF (CXFServlet) and Spring (ContextLoaderListener) I have registered the CXFServlet to listen on the / url. And I am declaring my beans in beans.xml.
When I start the web service with tomcat and go to the service url, then I can see the web service definition (e.g. methods, endpoint, wsdl link). But the problem is that when I click on the wsdl link, then I do not get the WSDL file, but instead I am recursively forwarded back to the same page, but each time the name of the web service address is appended:
localhost:8080/Test/accountEndpoint
localhost:8080/Test/accountEndpointaccountEndpoint
localhost:8080/Test/accountEndpointaccountEndpointaccountEndpoint
The service is a "code-first" service which a #WebService annotated java interface and a implementation class.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Test</display-name>
<servlet>
<servlet-name>cxf</servlet-name>
<display-name>cxf</display-name>
<description>Apache CXF Endpoint</description>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<bean id="account" class=".....AccountImpl" />
<jaxws:endpoint id="accountEndpoint" implementor="#account"
address="accountEndpoint" />
</beans>
As I understand it, CXF should automatically generate the WSDL file and provide it to me, when I click on the link, so I do not understand why that is not happening.
Specify the address this way, with a leading slash:
<jaxws:endpoint id="accountEndpoint" implementor="#account"
address="/accountEndpoint" />
Sorry, making a change, the above is not correct:
You are right, I am able to replicate the behavior with mapping CXFServlet to the "default" servlet path mapping of /, the fix that I could get to work for myself is to map it to /* instead:
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

getting exception: No bean named 'springSecurityFilterChain' is defined

I am learning spring security from reference material. release 3.1.2.RELEASE. As stated in that I have configured security:http tag like this
security-context.xml
<security:http auto-config="true">
<security:intercept-url pattern="/**" access="ROLE_USER"/>
</security:http>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:*-context.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>security</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>security</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
security-servlet.xml
<context:component-scan base-package="com.pokuri.security.mvc.controllers"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
But I am getting this exception when I start the application. If I remove security configuration my spring web application working fine. I went through the same kind of questions in stackoverflow. But no luck.
I think that the reason of your problem can be in that your xml configuration file for spring security isn't loaded when you start your web app.
To fix this you should specify all your XML config files in web.xml like that:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml, /WEB-INF/applicationContext.xml</param-value>
</context-param>
If you have your config files in classpath (not WEB-INF folder or it's subfolders) then you can specify list of config files in such way;
...
<param-value>
classpath:applicationContext.xml,
classpath:spitter-security.xml
</param-value>
...
And also you need to add special listener that will load your config files:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
I just added the bean definition in applicationContext.xml as Spring asked:
<bean id="springSecurityFilterChain" class="org.springframework.web.filter.DelegatingFilterProxy"/>
add this your web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml, /WEB-INF/spring-security.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- filter declaration for Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In case it helps anyone, I had renamed one of my packages but Eclipse doesn't auto-update your #ComponentScan paths, so make sure you change that too:
#ComponentScan(basePackages = "com.package.spring")
As of Spring Security 5.2.1-SNAPSHOT, this error occurred to me when I hadn't declared the <http/> element in security XML configuration.
I was trying a sample and I had configuration like
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER" />
</user-service>
</b:beans>
I had to change it to add <http/> like below.
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
<http />
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER" />
</user-service>
</b:beans>
For those who learning spring without xml may be this helps.
I faced the same exception when learning the spring without xml.
Found that i have register the spring security filter by extending the class AbstractSecurityWebApplicationInitializer but did not configure the spring security.
To configure the spring security i added below code and it works.
#Configuration
#EnableWebSecurity
public class SpringSecurityConfigInitializer extends
WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
UserBuilder users = User.withDefaultPasswordEncoder();
auth.inMemoryAuthentication().withUser(users.username("test").
password("test123").roles("EMPLOYEE"));
}
}
Above is just sample for my case but the exception was due to the missing configuration.

java.lang.VerifyError org.apache.cxf.transport.servlet.ServletTransportFactory overrides final method register.()V?

i'm trying to develop a new SOAP web service into my project using CXF and spring 2.5.6, but when i deploy the war file into tomcat 6 i got this exception :
java.lang.VerifyError org.apache.cxf.transport.servlet.ServletTransportFactory overrides final method register.()V
i'have done all the configurations into pom.xml, web.xml and application context files. :
this is the web.xml add lines for the WS :
<display-name>CXF Example Webservice</display-name>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
and i add these line into the applicationscontext file :
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- Spring manage ServiceBean -->
<bean id="savServ" class="com.otn.sav.SavServiceImpl" />
<!-- JAX-WS Service Endpoint -->
<jaxws:endpoint id="savService" implementor="#savServ" address="/savService" />
i think tha ther is a problem of "versionig" this why java can't load the class :
org.apache.cxf.transport.servlet.ServletTransportFactory
i try it serval times to solve this exception but unfortunately i can't resolve it
if any one can help please answer me ???????
ps : sorry for my bad english :)
Edit: look if you don't have some older jar on your classpath - this was my case (not sure how it happened but deleting them helped). Still, it produced another problem.

Spring ReloadableResourceBundleMessageSource configuration

I develop a simple Spring application which is my university task. There are 3 configuration files: web.xml, core-context.xml, dispatcher-servlet.xml and 1 file with default properties which is called messages.properties and is located in /WEB-INF/ folder.
In my application I have the following configuration of ReloadableResourceBundleMessageSource and it works fine:
core-context.xml
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="/WEB-INF/messages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:core-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
But it turned out that my task instruction says that I should configure ReloadableResourceBundleMessageSource bean in dispatcher-servlet.xml. The problem is that whenever I remove the above configuration from core-context.xml and put it in dispatcher-servlet.xml my locals are no longer displayed.
Could you explain to me why the problem occurs?
What is a difference between putting bean configuration inside core-context.xml and dispatcher-servlet.xml?
You have not posted your dispatcher-servlet.xml but I believe it is not being initialized by the spring container because it is not declared anywhere. If you must have another file called dispatcher-servlet.xml as you specify then you can just import it in your core-context.xml. This should solve your problem.

Jetty 7 web.xml configuration for Spring web 3.0.5

I configured a Jetty 7 embedded mode in eclipse indigo. When i start jetty in eclipse it seems not loading my web.xml and spring-servlet.xml configuration. I search on the net, it seems everybody doing the same configuration as me but mine doesn't load. Did i forgot something ? or Jetty 7 configuration its different than jetty 6 ?
Main.java
Server server = new Server(8080);
WebAppContext context = new WebAppContext();
context.setResourceBase("../jettyserver/webapp");
context.setContextPath("/");
context.setParentLoaderPriority(true);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ context, new DefaultHandler()});
server.setHandler(context);
try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
}
web.xml
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.jetty.controller" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Not an expert here but if you are using eclipse I'd say there could be a problem with your resource base.
Depending on how you use Eclipse here (WTP, Maven etc) the compiled code will end up in the target folder somewhere. However your JSP and all may not follow or may not be where you'd think they are.
Compile your code and look in your target folder see where it is. I do something similar but it's testing code so I don't really care if the paths are linked to my IDE. our versions are pretty much identical, applicative differences aside, except for these :
WebAppContext webapp = new WebAppContext();
webapp.setDescriptor("target/app/WEB-INF/web.xml");
webapp.setResourceBase("target/app");
webapp.setContextPath("/app");
As you can see here the root path of the application run-time within Eclipse is your project's root path in your workspace. I set mine so it finds it's stuff relative to the project's root path, hence the target in there.
If however you are looking for code that runs in both your environment and once deployed you could probably change the root folder in the run configuration for your particular application and set it to target directly (or whatever works for you).
Sorry for not being more decisive here,
Anyways, hope this helps.

Resources