{"id":13000,"date":"2016-08-16T18:44:00","date_gmt":"2016-08-16T16:44:00","guid":{"rendered":"https:\/\/touk.pl\/blog\/?guid=839edd0238f706b0dfc0e7e6e8f505ae"},"modified":"2023-04-27T11:30:18","modified_gmt":"2023-04-27T09:30:18","slug":"deploy-wsdl-file-as-osgi-bundle-in-apache-karaf","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2016\/08\/16\/deploy-wsdl-file-as-osgi-bundle-in-apache-karaf\/","title":{"rendered":"Deploy WSDL file as OSGI Bundle in Apache Karaf"},"content":{"rendered":"<h2 id=\"introduction\">Introduction<\/h2>\n<p>WSDL file describes webservices. Java classes are often generated from WSDL. For this purpose, we could use command line tools (e. g. <a href=\"http:\/\/cxf.apache.org\/docs\/wsdl-to-java.html\">wsdl2Java<\/a> or <a href=\"http:\/\/docs.oracle.com\/javase\/6\/docs\/technotes\/tools\/share\/wsimport.html\">wsimport<\/a>) or using <a href=\"http:\/\/cxf.apache.org\/docs\/maven-cxf-codegen-plugin-wsdl-to-java.html\">maven plugin<\/a>.<\/p>\n<p>From the other side, we have <a href=\"http:\/\/karaf.apache.org\/\">Apache Karaf<\/a> which is OSGI container. Karaf has installed by default many deployers for creating OSGi bundles from files, e. g. <a href=\"http:\/\/karaf.apache.org\/manual\/latest\/#_blueprint_deployer\">Blueprint deployer<\/a>, <a href=\"http:\/\/karaf.apache.org\/manual\/latest\/#_spring_deployer\">Spring deployer<\/a> or <a href=\"http:\/\/karaf.apache.org\/manual\/latest\/#_war_deployer\">War deployer<\/a>.<\/p>\n<p>It is easy to generate java classes from WSDL file and also to create custom deployer for Karaf, so why do not join these two features?<\/p>\n<h2 id=\"installation-of-wsdl-deployer\">Installation of WSDL deployer<\/h2>\n<p>Source code of my WSDL deployer is provided <a href=\"https:\/\/github.com\/alien11689\/wsdl-deployer\">here<\/a>. You can download and build it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">mvn clean install\r\n<\/pre>\n<p>We also need Karaf. I will use the newest version 4.0.5. It could be download from <a href=\"http:\/\/karaf.apache.org\/download.html\">Karaf website<\/a>. When you download and unpack it, you can run it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ cd PUT_PATH_TO_KARAF_DIR_HERE\r\n$ .\/bin\/karaf\r\n    __ __                  ____      \r\n   \/ \/\/_\/____ __________ _\/ __\/      \r\n  \/ ,&lt;  \/ __ <code data-enlighter-language=\"raw\" class=\"EnlighterJSRAW\">\/ ___\/ __ <\/code>\/ \/_        \r\n \/ \/| |\/ \/_\/ \/ \/  \/ \/_\/ \/ __\/        \r\n\/_\/ |_|\\__,_\/_\/   \\__,_\/_\/         \r\n\r\nApache Karaf (4.0.5)\r\n\r\nHit '&lt;tab&gt;' for a list of available commands\r\nand '[cmd] --help' for help on a specific command.\r\nHit '&lt;ctrl-d&gt;' or type 'system:shutdown' or 'logout' to shutdown Karaf.\r\n\r\nkaraf@root()&gt;\r\n<\/pre>\n<p>and install commons-io and wsdl-delpoyer bundles:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">karaf@root()&gt; install -s mvn:org.apache.servicemix.bundles\/org.apache.servicemix.bundles.commons-io\/1.4_3\r\nBundle ID: 52\r\nkaraf@root()&gt; install -s mvn:com.github.alien11689.karaf\/wsdl-deployer\/1.0.0-SNAPSHOT\r\nBundle ID: 53\r\n<\/pre>\n<h2 id=\"install-wsdl-from-karaf-shell\">Install WSDL from Karaf shell<\/h2>\n<p>I will test deployer using WSDL file named <code>exampleService-2.0.0.wsdl<\/code> (provided WSDL is similar to <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd323317(v=vs.85).aspx\">this<\/a>, but has another namespace in types schama for testing purpose):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;?xml version=\"1.0\"?&gt;\r\n&lt;wsdl:definitions\r\n    xmlns:soap=\"http:\/\/schemas.xmlsoap.org\/wsdl\/soap\/\"\r\n    xmlns:wsu=\"http:\/\/docs.oasis-open.org\/wss\/2004\/01\/oasis-200401-wss-wssecurity-utility-1.0.xsd\"\r\n    xmlns:soapenc=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\/\"\r\n    xmlns:tns=\"http:\/\/Example.org\"\r\n    xmlns:sns=\"http:\/\/Example.org\/schema\"\r\n    xmlns:wsa=\"http:\/\/schemas.xmlsoap.org\/ws\/2004\/08\/addressing\"\r\n    xmlns:wsp=\"http:\/\/schemas.xmlsoap.org\/ws\/2004\/09\/policy\"\r\n    xmlns:wsap=\"http:\/\/schemas.xmlsoap.org\/ws\/2004\/08\/addressing\/policy\"\r\n    xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"\r\n    xmlns:msc=\"http:\/\/schemas.microsoft.com\/ws\/2005\/12\/wsdl\/contract\"\r\n    xmlns:wsaw=\"http:\/\/www.w3.org\/2006\/05\/addressing\/wsdl\"\r\n    xmlns:soap12=\"http:\/\/schemas.xmlsoap.org\/wsdl\/soap12\/\"\r\n    xmlns:wsa10=\"http:\/\/www.w3.org\/2005\/08\/addressing\"\r\n    xmlns:wsx=\"http:\/\/schemas.xmlsoap.org\/ws\/2004\/09\/mex\"\r\n  targetNamespace=\"http:\/\/Example.org\"\r\n    xmlns:wsdl=\"http:\/\/schemas.xmlsoap.org\/wsdl\/\"&gt;\r\n    &lt;wsdl:types&gt;\r\n        &lt;xsd:schema targetNamespace=\"http:\/\/Example.org\/schema\" elementFormDefault=\"qualified\" &gt;\r\n            &lt;xsd:element name=\"Add\"&gt;\r\n                &lt;xsd:complexType&gt;\r\n                    &lt;xsd:sequence&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"a\" type=\"xsd:int\" \/&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"b\" type=\"xsd:int\" \/&gt;\r\n                    &lt;\/xsd:sequence&gt;\r\n                &lt;\/xsd:complexType&gt;\r\n            &lt;\/xsd:element&gt;\r\n            &lt;xsd:element name=\"AddResponse\"&gt;\r\n                &lt;xsd:complexType&gt;\r\n                    &lt;xsd:sequence&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"result\" type=\"xsd:int\" \/&gt;\r\n                    &lt;\/xsd:sequence&gt;\r\n                &lt;\/xsd:complexType&gt;\r\n            &lt;\/xsd:element&gt;\r\n            &lt;xsd:element name=\"Subtract\"&gt;\r\n                &lt;xsd:complexType&gt;\r\n                    &lt;xsd:sequence&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"a\" type=\"xsd:int\" \/&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"b\" type=\"xsd:int\" \/&gt;\r\n                    &lt;\/xsd:sequence&gt;\r\n                &lt;\/xsd:complexType&gt;\r\n            &lt;\/xsd:element&gt;\r\n            &lt;xsd:element name=\"SubtractResponse\"&gt;\r\n                &lt;xsd:complexType&gt;\r\n                    &lt;xsd:sequence&gt;\r\n                        &lt;xsd:element minOccurs=\"0\" name=\"result\" type=\"xsd:int\" \/&gt;\r\n                    &lt;\/xsd:sequence&gt;\r\n                &lt;\/xsd:complexType&gt;\r\n            &lt;\/xsd:element&gt;\r\n        &lt;\/xsd:schema&gt;\r\n    &lt;\/wsdl:types&gt;\r\n    &lt;wsdl:message name=\"ICalculator_Add_InputMessage\"&gt;\r\n        &lt;wsdl:part name=\"parameters\" element=\"sns:Add\" \/&gt;\r\n    &lt;\/wsdl:message&gt;\r\n    &lt;wsdl:message name=\"ICalculator_Add_OutputMessage\"&gt;\r\n        &lt;wsdl:part name=\"parameters\" element=\"sns:AddResponse\" \/&gt;\r\n    &lt;\/wsdl:message&gt;\r\n    &lt;wsdl:message name=\"ICalculator_Subtract_InputMessage\"&gt;\r\n        &lt;wsdl:part name=\"parameters\" element=\"sns:Subtract\" \/&gt;\r\n    &lt;\/wsdl:message&gt;\r\n    &lt;wsdl:message name=\"ICalculator_Subtract_OutputMessage\"&gt;\r\n        &lt;wsdl:part name=\"parameters\" element=\"sns:SubtractResponse\" \/&gt;\r\n    &lt;\/wsdl:message&gt;\r\n    &lt;wsdl:portType name=\"ICalculator\"&gt;\r\n        &lt;wsdl:operation name=\"Add\"&gt;\r\n            &lt;wsdl:input wsaw:Action=\"http:\/\/Example.org\/ICalculator\/Add\" message=\"tns:ICalculator_Add_InputMessage\" \/&gt;\r\n            &lt;wsdl:output wsaw:Action=\"http:\/\/Example.org\/ICalculator\/AddResponse\" message=\"tns:ICalculator_Add_OutputMessage\" \/&gt;\r\n        &lt;\/wsdl:operation&gt;\r\n        &lt;wsdl:operation name=\"Subtract\"&gt;\r\n            &lt;wsdl:input wsaw:Action=\"http:\/\/Example.org\/ICalculator\/Subtract\" message=\"tns:ICalculator_Subtract_InputMessage\" \/&gt;\r\n            &lt;wsdl:output wsaw:Action=\"http:\/\/Example.org\/ICalculator\/SubtractResponse\" message=\"tns:ICalculator_Subtract_OutputMessage\" \/&gt;\r\n        &lt;\/wsdl:operation&gt;\r\n    &lt;\/wsdl:portType&gt;\r\n    &lt;wsdl:binding name=\"DefaultBinding_ICalculator\" type=\"tns:ICalculator\"&gt;\r\n        &lt;soap:binding transport=\"http:\/\/schemas.xmlsoap.org\/soap\/http\" \/&gt;\r\n        &lt;wsdl:operation name=\"Add\"&gt;\r\n            &lt;soap:operation soapAction=\"http:\/\/Example.org\/ICalculator\/Add\" style=\"document\" \/&gt;\r\n            &lt;wsdl:input&gt;\r\n                &lt;soap:body use=\"literal\" \/&gt;\r\n            &lt;\/wsdl:input&gt;\r\n            &lt;wsdl:output&gt;\r\n                &lt;soap:body use=\"literal\" \/&gt;\r\n            &lt;\/wsdl:output&gt;\r\n        &lt;\/wsdl:operation&gt;\r\n        &lt;wsdl:operation name=\"Subtract\"&gt;\r\n            &lt;soap:operation soapAction=\"http:\/\/Example.org\/ICalculator\/Subtract\" style=\"document\" \/&gt;\r\n            &lt;wsdl:input&gt;\r\n                &lt;soap:body use=\"literal\" \/&gt;\r\n            &lt;\/wsdl:input&gt;\r\n            &lt;wsdl:output&gt;\r\n                &lt;soap:body use=\"literal\" \/&gt;\r\n            &lt;\/wsdl:output&gt;\r\n        &lt;\/wsdl:operation&gt;\r\n    &lt;\/wsdl:binding&gt;\r\n    &lt;wsdl:service name=\"CalculatorService\"&gt;\r\n        &lt;wsdl:port name=\"ICalculator\" binding=\"tns:DefaultBinding_ICalculator\"&gt;\r\n            &lt;soap:address location=\"http:\/\/localhost\/ICalculator\" \/&gt;\r\n        &lt;\/wsdl:port&gt;\r\n    &lt;\/wsdl:service&gt;\r\n&lt;\/wsdl:definitions&gt;\r\n<\/pre>\n<p>We could install it via command:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">karaf@root()&gt; install -s wsdl:file:PUT_PATH_TO_WSDL_HERE\/exampleService-2.0.0.wsdl\\$package=org.github.alien11689.example&amp;s1=http:\/\/Example.org\/schema&amp;t1=org.github.alien11689.example.schema\r\nBundle ID: 54\r\n<\/pre>\n<p>File must have format <code>${bundleSymbolicName}-${version}.wsdl<\/code>.<\/p>\n<p>Provided options are:<\/p>\n<ul>\n<li><code>package<\/code> &#8211; allows to change package of generated interface<\/li>\n<li>pair <code>s1<\/code> and <code>t1<\/code> &#8211; maps schema in WSDL to package (WSDL deployer is in draft verion nowadays provides options to map only one schema).<\/li>\n<\/ul>\n<p>Karaf has installed this file:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">karaf@root()&gt; headers 54\r\n\r\nBundle 54\r\n---------\r\nManifest-Version = 2\r\n\r\nBundle-ManifestVersion = 2\r\nBundle-SymbolicName = exampleService-2.0.0.wsdl\r\nBundle-Version = 2.0.0\r\n\r\nExport-Package =\r\n    org.github.alien11689.example.schema;version=2.0.0,\r\n    org.github.alien11689.example;version=2.0.0\r\nImport-Package =\r\n    javax.jws,\r\n    javax.jws.soap,\r\n    javax.xml.bind.annotation,\r\n    javax.xml.namespace,\r\n    javax.xml.ws\r\n<\/pre>\n<h2 id=\"install-wsdl-by-putting-it-into-karaf-drop-folder\">Install WSDL by putting it into Karaf drop folder<\/h2>\n<p>You can also install WSDL file by copying it to <code>deploy<\/code> directory:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">cp PUT_PATH_TO_WSDL_HERE\/exampleService-2.0.0.wsdl PUT_PATH_TO_KARAF_DIR_HERE\/deploy\/deployedExampleService-2.0.0.wsdl<\/pre>\n<p>It is much more simple to do, but do not allow for customization (e. g. namespace to package mapping). It creates bundle:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">karaf@root()&gt; list | grep deployedExampleService\r\n55 | Active |  80 | 2.0.0          | deployedExampleService-2.0.0.wsdl\r\nkaraf@root()&gt; headers 55\r\n\r\nBundle 55\r\n---------\r\nManifest-Version = 2\r\n\r\nBundle-ManifestVersion = 2\r\nBundle-SymbolicName = deployedExampleService-2.0.0.wsdl\r\nBundle-Version = 2.0.0\r\n\r\nExport-Package =\r\n    org.example;version=2.0.0,\r\n    org.example.schema;version=2.0.0\r\nImport-Package =\r\n    javax.jws,\r\n    javax.jws.soap,\r\n    javax.xml.bind.annotation,\r\n    javax.xml.namespace,\r\n    javax.xml.ws\r\n<\/pre>\n<h2 id=\"how-does-it-work\">How does it work?<\/h2>\n<p>Deployer uses <code>wsimport<\/code> command to create in temporary directory and compile generated java classes. Compiled class are packed with <code>MANIFEST.MF<\/code> into <code>service.jar<\/code> and such jar is really installed in OSGi container. For example, my temporary directory is <code>\/tmp\/4ff81631-3c08-487a-b731-1f95c568026f<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ tree \/tmp\/4ff81631-3c08-487a-b731-1f95c568026f\r\n\/tmp\/4ff81631-3c08-487a-b731-1f95c568026f\r\n\u251c\u2500\u2500 Jaxb-binding.xml\r\n\u251c\u2500\u2500 Jaxws-binding.xml\r\n\u251c\u2500\u2500 service.wsdl\r\n\u251c\u2500\u2500 src\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 org\r\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 github\r\n\u2502\u00a0\u00a0         \u2514\u2500\u2500 alien11689\r\n\u2502\u00a0\u00a0             \u2514\u2500\u2500 example\r\n\u2502\u00a0\u00a0                 \u251c\u2500\u2500 CalculatorService.java\r\n\u2502\u00a0\u00a0                 \u251c\u2500\u2500 ICalculator.java\r\n\u2502\u00a0\u00a0                 \u2514\u2500\u2500 schema\r\n\u2502\u00a0\u00a0                     \u251c\u2500\u2500 Add.java\r\n\u2502\u00a0\u00a0                     \u251c\u2500\u2500 AddResponse.java\r\n\u2502\u00a0\u00a0                     \u251c\u2500\u2500 ObjectFactory.java\r\n\u2502\u00a0\u00a0                     \u251c\u2500\u2500 package-info.java\r\n\u2502\u00a0\u00a0                     \u251c\u2500\u2500 Subtract.java\r\n\u2502\u00a0\u00a0                     \u2514\u2500\u2500 SubtractResponse.java\r\n\u2514\u2500\u2500 target\r\n    \u251c\u2500\u2500 org\r\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 github\r\n    \u2502\u00a0\u00a0     \u2514\u2500\u2500 alien11689\r\n    \u2502\u00a0\u00a0         \u2514\u2500\u2500 example\r\n    \u2502\u00a0\u00a0             \u251c\u2500\u2500 CalculatorService.class\r\n    \u2502\u00a0\u00a0             \u251c\u2500\u2500 ICalculator.class\r\n    \u2502\u00a0\u00a0             \u2514\u2500\u2500 schema\r\n    \u2502\u00a0\u00a0                 \u251c\u2500\u2500 Add.class\r\n    \u2502\u00a0\u00a0                 \u251c\u2500\u2500 AddResponse.class\r\n    \u2502\u00a0\u00a0                 \u251c\u2500\u2500 ObjectFactory.class\r\n    \u2502\u00a0\u00a0                 \u251c\u2500\u2500 package-info.class\r\n    \u2502\u00a0\u00a0                 \u251c\u2500\u2500 Subtract.class\r\n    \u2502\u00a0\u00a0                 \u2514\u2500\u2500 SubtractResponse.class\r\n    \u2514\u2500\u2500 service.jar\r\n<\/pre>\n<p>And my <code>service.jar<\/code> contains:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ jar tf \/tmp\/4ff81631-3c08-487a-b731-1f95c568026f\/target\/service.jar\r\nMETA-INF\/\r\nMETA-INF\/MANIFEST.MF\r\norg\/\r\norg\/github\/\r\norg\/github\/alien11689\/\r\norg\/github\/alien11689\/example\/\r\norg\/github\/alien11689\/example\/schema\/\r\norg\/github\/alien11689\/example\/schema\/Add.class\r\norg\/github\/alien11689\/example\/schema\/ObjectFactory.class\r\norg\/github\/alien11689\/example\/schema\/Subtract.class\r\norg\/github\/alien11689\/example\/schema\/SubtractResponse.class\r\norg\/github\/alien11689\/example\/schema\/package-info.class\r\norg\/github\/alien11689\/example\/schema\/AddResponse.class\r\norg\/github\/alien11689\/example\/ICalculator.class\r\norg\/github\/alien11689\/example\/CalculatorService.class\r\n<\/pre>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>WSDL generation and Karaf deployers could be easily joined and simplified creation of OSGi bundles without explicite creation of jar. Provided WSDL deployer is just draft, but could be very useful when we have many WSDLs and do not want to create separate artifacts for them.<\/p>\n<p>Source code of WSDL deployer is provided <a href=\"https:\/\/github.com\/alien11689\/wsdl-deployer\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"Introduction WSDL file describes webservices. Java classes are often generated from WSDL. For this purpose, we could use&hellip;\n","protected":false},"author":54,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[594,603,68,44,381],"class_list":{"0":"post-13000","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-api","8":"tag-deployer","9":"tag-java","10":"tag-osgi","11":"tag-soap"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=13000"}],"version-history":[{"count":9,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13000\/revisions"}],"predecessor-version":[{"id":15667,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13000\/revisions\/15667"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=13000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=13000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=13000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}