Cloudfoundry: Deploying a standalone application using Spring and RabbitMQ - spring

I am trying to deploy a standalone application to CloudFoundry. I am using a Spring ApplicationContext in my main-method to initialize Spring and I have a simple Bean to handle the messaging with RabbitMQ.
In the spring.xml I have configured RabbitMQ and in the pom file I have added the necessary dependencies for cglib-nodep, spring-rabbit and cloudfoundry-runtime. I am further more using the maven-assembly-plugin plugin to create a single jar file which contains all the libraries, and I then deploy it to cloudfoundry with the vmc-tool.
When I deploy the jar-file to CloudFoundry I am getting the following error:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace
[http://www.springframework.org/schema/context]
Offending resource: class path resource [spring.xml]
[stacktrace ommited]
Here is my spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
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
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.7.xsd">
<context:component-scan base-package="mypackage" />
<!-- Obtain a connection to the RabbitMQ via cloudfoundry-runtime: -->
<cloud:rabbit-connection-factory id="connectionFactory"/>
<!-- Set up the AmqpTemplate/RabbitTemplate: -->
<rabbit:template connection-factory="connectionFactory"/>
<!-- Request that queues, exchanges and bindings be automatically
declared on the broker: -->
<rabbit:admin connection-factory="connectionFactory"/>
<!-- Declare the "messages" queue: -->
<rabbit:queue name="messages" durable="true"/>
</beans>
And the configuration of the maven-assembly-plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>at.ac.tuwien.infosys.dse2013s.group17.allocator.ui.StartUpAllocator</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
What could be the reason for the above error? Is there something wrong with how I configured the maven-assembly-plugin, or is there really a problem in the spring.xml?
Update
I was able to solve the error, by adding the spring-context dependency to my root pom as a managed dependency and then referencing it from my module without the version element. Now I am getting the same error but this time the Exception complains about the http://schema.cloudfoundry.org/spring schema.

[Update] I recommend to take a look at the cf-maven-plugin, which makes it much easier to deploy to CloudFoundry, so its no longer needed to work with the vmc tool directly. The GitHub page explains both howto deploy normal and standalone applications with this plugin, and also explains to use the appassembler-maven-plugin for standalone applications. This blog post is also useful to get started.
[/Update]
It turned out I was deploying the application in a wrong way to CloudFoundry. I was using the maven-assembly-plugin, which unpacked the class files of all dependencies into the jar file. In fact I had to use the appassembler-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<assembledirectory>target</assembledirectory>
<programs>
<program>
<mainClass>my.package.myclass</mainClass>
</program>
</programs>
</configuration>
</execution>
</executions>
</plugin>
I then deployed the application to CloudFoundry like this from the the target/ folder
vmc push <myappname> --path=appassembler
As run command I needed to choose the name of the run script in the appassembler/bin folder. For example bin/start-up-myapp.

Related

How to externalise .properties files when deploying a Spring Boot WAR in Wildfly Server?

I am developing a web application using Spring Boot, and want to generate war instead of jar.
It works fine using the conversion from jar to war described here : http://spring.io/guides/gs/convert-jar-to-war/
But I want to externalize the application.properties from the war, because I want to be able to modify it without opening the war archive.
I already defined the spring-boot-maven plugin.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
com.application.Application
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
I think I need to add Dependency: config to my manifest file.
So, I've done it like that :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>config</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
But when I launch the Application.war on Wildfly 8.4, I've got this
{"JBAS014671: Failed services" => {"jboss.module.service.\"deployment.Application.war\".main" => "org.jboss.msc.service.StartException in service jboss.module.service.\"deployment.screening.war\".main: JBAS018759: Failed to load module: deployment.Application.war:main
Caused by: org.jboss.modules.ModuleNotFoundException: config:main"}}
I would like that my application start with my custom MANIFEST.MF (with Dependency: config) so that I can externalize my application.properties file.
Thank you.
The problem was on the server side !
When you specify a package, you need to add a module.xml file with a Wildfly server.
So in modules/config/main/, I've added my application.properties and a module.xml file that contains :
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="config">
<resources>
<resource-root path="."/>
</resources>
</module>
Thank you for your response #NielsNet.

JAXB2 Basics Plugins - Issue with schemaLocation in my External binding customization file

I am using JAXB to generate classes from my XSD file. I would like to have the classes that are generated implement a common interface. So I am trying out the JAXB2 Basics plugin with the external binding file approach to do this. This is my custom binding file:
customBindingFile.xjb
<?xml version="1.0"?>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="abc-api.xsd">
<jxb:bindings node="//xs:complexType[#name='MyClass']">
<inheritance:implements>com.kuldeep.CommonInterface</inheritance:implements>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
Following is my maven plugin in pom file for source generation:
Note the comment added by me is the change I made to this existing plugin entry.
pom.xml
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.plugin.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<!-- **extensions and args added by me** -->
<extensions>
<extension>org.jvnet.jaxb2_commons:jaxb2-basics:0.9.2</extension>
</extensions>
<args>
<arg>-Xinheritance</arg>
</args>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<defaultOptions>
<bindingFiles>
<bindingFile>src/main/resources/jaxws_binding.xml</bindingFile>
<bindingFile>src/main/resources/jaxb_binding.xml</bindingFile>
</bindingFiles>
</defaultOptions>
<wsdlOptions>
......
<wsdlOption>
<wsdl>${project.build.directory}/generated/framework/cxf/abc-api-inline.wsdl</wsdl>
<!-- **bindingFile added by me** -->
<bindingFile>src/main/resources/customBindingFile.xjb</bindingFile>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<!-- **dependency added by me** -->
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.9.2</version>
</dependency>
</dependencies>
</plugin>
The issue that I have is my schema file abc-api.xsd resides in some other project, so when I try to do maven install to generate my classes, I get error saying abc-api.xsd is not a part of this compilation.
[ERROR] Failed to execute goal
org.apache.cxf:cxf-codegen-plugin:3.0.3:wsdl2java (generate-sources)
on project : Execution generate-sources of goal
org.apache.cxf:cxf-codegen-plugin:3.0.3:wsdl2java failed:
file:/I:/project/src/main/resources/customBindingFile.xjb [9,56]:
"file:/I:/project/src/main/resources/abc-api.xsd" is not a part of
this compilation. Is this a mistake for
"file:/I:/project/src/main/resources/jaxb_binding.xml"? -> [Help 1]
And if I remove the schemaLocation attribute from customBindingFile.xjb it does not work and gives error:
XPath evaluation of "//xs:complexType[#name='MyClass']" results in
empty target node
So my question is how can I avoid providing the specific schema file name/location in customBindingFile.xjb and just have it applied to whatever xsd it's using to generate the classes.
With help from our Architect, I was able to resolve this issue. I added a jaxws binding file and used prefix-less xpath query in there to match my request elements.
This way I don't need to provide schema location anywhere and it will be applied to the specific WSDL based on the XPath query.
jaxws_binding_inheritance.xml
<jaxws:bindings version="2.0" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance" jaxb:extensionBindingPrefixes="inheritance xjc"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
<jaxws:bindings
node="*[local-name()='definitions']/*[local-name()='types']/*[local-name()='schema' and
(#targetNamespace='urn:net:mycompany:api:abc')]">
<jaxb:bindings
node="//*[local-name()='element' and
not(#name = 'ExcludeThisRequest' or #name = 'AlsoExcludeThisRequest') and
(substring(#name, string-length(#name) - string-length('Request') +1) = 'Request')]/*[local-name()='complexType']">
<inheritance:implements>com.kuldeep.CommonRequest</inheritance:implements>
</jaxb:bindings>
</jaxws:bindings>
</jaxws:bindings>
And added that jaxws binding file (jaxws_binding_inheritance.xml) under wsdloption for the wsdl where I wanted to apply that.
pom.xml
<wsdlOption>
<wsdl>${project.build.directory}/generated/framework/cxf/abc-api-inline.wsdl</wsdl>
<bindingFiles>
<bindingFile>src/main/resources/jaxws_binding_inheritance.xml</bindingFile>
</bindingFiles>
</wsdlOption>

Spring 4.2 - Dependancy Injection - http://www.springframework.org/schema/p error

I'm doing a book simple example for DI where execution returns:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/p]
Offending resource: class path resource [META-INF/spring/app-context.xml]
where app-context.xml is :
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="provider" class="com.apress.prospring4.ch2.HelloWorldMessageProvider"/>
<bean id="renderer" class="com.apress.prospring4.ch2.StandardOutMessageRenderer" p:messageProvider-ref="provider"/>
</beans>
All prevous exercices are working fine...
External additional exercice on bean without DI works fine also...
Using Spring 4.2, Maven 3, JVM 1.8.
Any idea?
EDIT I've changed the p:notation to
<bean id="renderer" class="com.apress.prospring4.ch2.StandardOutMessageRenderer">
<property name="messageProvider" ref="provider" />
</bean>
and removed the p namespace reference so that app now works, which is good because I'm a learning newbie there.
Nevertheless I keep wondering how to have p namespace working!
As a side note i don't see any "http://www.springframework.org/schema/p" despite I can see a "http://www.springframework.org/schema/beans"; Probably my lack of knowledge.
I encountered this error when packaging the application into a single executable Jar (worked when running directly in eclipse/IntelliJ).
The problem was the spring.schemas file was being overwritten in the META-INF folder during the packaging.
You can solve that by using the maven shade plugin, and building the jar using mvn clean package
You'll need to use the transformers to append the spring files like so (and change the main class to be your own)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>tom.lightwaverf.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

Getting all of it to work: War, OSGI, Spring Beans, Maven

Trying to deploy a war with a bean file in a Fuse Servicemix (version 4.3.1). I'm using maven to build my war. I can't seem to get this to work. Can anyone provide a website that can tell me how to do this?
This website tells me what to put in the web.xml file but doesn't explain the rest.
http://fusesource.com/docs/esbent/7.0/esb_deploy_osgi/BuildWar-Spring.html.
I've tried several solutions and methods over the course of 19 days. Everyone seems to skin this cat differently but none of them work for me.
fat war (SOLVED):
See answer below
skinny war:
Seems impossible in osgi. Need to manually import too many packages.
This link appears to solve it but seems there a lot of nasty side effects.
http://davidvaleri.wordpress.com/2011/08/17/deploying-spring-mvc-based-web-applications-to-osgi-using-apache-servicemix/
You need to add the Spring OSGi ContextLoaderListener to your web.xml otherwise it doesn't work. You'll also need dependencies to Spring-DM 1.2.1.
Take a look at Pax Web Spring sample and especially the web.xml in it. It's a working example on how to use Spring in Karaf / Fuse-ServiceMix ...
I guess I pointed you to the wrong sample. You need t use the following.
contextClass
org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
Fat War solution
This is the minimum viable solution that worked for me. I played around trying to remove things and it broke as soon as I did, often without even posting an error message.
directory structure:
src/main/java/test/Test.java
src/main/webapp/WEB-INF/web.xml
src/main/webapp/WEB-INF/applicationContext.xml
pom.xml
...
<groupId>test</groupId>
<artifactId>war-bean-test</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.osgi</groupId>
<artifactId>spring-osgi-web</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<instructions>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<!-- IMPORTANT resolution:=optional fixes bug where bundle fails to load unnecessary packages such as bsh. You also need javax.servlet. In Servicemix 4.3.1 it is provided by geronimo servlet. -->
<Import-Package>
javax.servlet
*; resolution:=optional
</Import-Package>
<Export-Package></Export-Package>
<!-- IMPORTANT explicitly adding the jars fixes the numerous CassNotFoundExceptions -->
<Bundle-ClassPath>
.,WEB-INF/classes,{maven-dependencies}
</Bundle-ClassPath>
<Web-ContextPath>warbeantest</Web-ContextPath>
<Webapp-Context>warbeantest</Webapp-Context>
<!-- adding inline=true to Embed-Dependency causes {maven-dependencies} to not work and you will have to add every jar by hand -->
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>war-bean-test</display-name>
<description>war-bean-test</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- If you remove this then the spring beans will still work, but you wont be able to fetch services and resources from other osgi bundles -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
applicationContext.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="test" class="test.Test">
<property name="value" value="1" />
</bean>
</beans>
Test.java
package test;
public class Test {
private int value = 0;
public TestImpl() { }
public void setValue(int value) {
// Should print to console when you load into Fuse Servicemix
System.out.println("testing...");
this.value = value;
}
public int getValue() { return value; }
}

Change the execution directory of a cxf-codegen-plugin

I'm building some tooling to (automatically) convert a large ANT project to a Maven structure. The project contains webservices. Therefore, I'm not able to change the input wsdl / xsd files. This is my input wsdl file. It contains a reference to a types definition from the poject base dir.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://schemas.test.com/test" name="Test">
<wsdl:import namespace="http://schemas.test.com/test" location="./src/wsdl/Test.xsd"/>
<wsdl:types>
</wsdl:types>
</wsdl:definitions>
This is my maven plugin configuration:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<wsdlRoot>${project.build.directory}/../src/wsdl/</wsdlRoot>
<includes>
<include>**/*.wsdl</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Building the submodule works fine, since the cfx-codegen-plugin seems to take the ${project.basedir} as execution root directory.
However, when I try to build the complete multimodule project, the cfx-codegen-plugin seems to revert to the project.parent.basedir. I get the following build error:
Caused by : WSDLException (at /wsdl:definitions/wsdl:import): faultCode=PARSER_ERROR: Problem parsing './src/wsdl/Test.xsd'.: java.io.FileNotFoundException: C:\Users\test\Desktop\multimod\src\wsdl\Test.xsd (The system cannot find the path specified)
Does anyone know how to:
Change the execution root dir of a plugin in a specific maven phase?
Or force the cfx-codegen-plugin to use an alternative execution root?
Thanks,
sjaak

Resources