Use OpenStack4j in an OSGi platform - osgi

I want to use OpenStack4j in an OSGi platform. Specifically I'm using Apache Karaf OSGi runtime (based on Apache Felix OSGi implementation).
Issue arises when OpenStack4j tries to discovers Connectors. Based on Getting started official documentation guide, I'm trying to instantiate a v2.0 client with this line:
OSClient os = OSFactory.builder()
.endpoint("http://host:5000/v2.0")
.credentials("user", "password")
.tenantName("tenant")
.authenticate();
And I'm getting this exception:
Caused by: java.lang.ExceptionInInitializerError
at org.openstack4j.openstack.internal.OSAuthenticator.authenticateV2(OSAuthenticator.java:77)
at org.openstack4j.openstack.internal.OSAuthenticator.invoke(OSAuthenticator.java:41)
at org.openstack4j.openstack.client.OSClientBuilder$ClientV2.authenticate(OSClientBuilder.java:84)
at org.openstack4j.openstack.client.OSClientBuilder$ClientV2.authenticate(OSClientBuilder.java:65)
... 19 more
Caused by: java.lang.NullPointerException
at org.openstack4j.core.transport.internal.HttpExecutor.initService(HttpExecutor.java:32)
at org.openstack4j.core.transport.internal.HttpExecutor.<init>(HttpExecutor.java:25)
at org.openstack4j.core.transport.internal.HttpExecutor.<clinit>(HttpExecutor.java:20)
... 27 more
It seems to be related with Connector discovery, but I'm not sure.
OpenStack4j does not support OSGi, I asked for it. I tried to solve the issue declaring a Apache Karaf feature, based on HTTPClient 4 like this:
<?xml version="1.0" encoding="UTF-8"?>
<features>
<feature name="openstack4j" version="${openstack4j-version}">
<feature version="${openstack4j-version}">openstack4j-httpclient</feature>
<bundle dependency="true">mvn:com.google.guava/guava/17.0</bundle>
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-databind/2.3.5</bundle>
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-annotations/2.3.5</bundle>
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-core/2.3.5</bundle>
<bundle dependency="true">mvn:com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.3.5</bundle>
<bundle dependency="true">mvn:org.yaml/snakeyaml/1.14</bundle>
<bundle dependency="true">wrap:mvn:com.google.code.findbugs/jsr305/2.0.0</bundle>
<bundle>wrap:mvn:org.pacesys/openstack4j-core/${openstack4j-version}</bundle>
</feature>
<feature name="openstack4j-httpclient" version="${openstack4j-version}">
<bundle dependency="true">wrap:mvn:commons-logging/commons-logging/${commons.logging.version}</bundle>
<bundle dependency="true">wrap:mvn:org.apache.httpcomponents/httpclient/4.3.1</bundle>
<bundle dependency="true">wrap:mvn:org.apache.httpcomponents/httpcore/4.3</bundle>
<bundle>wrap:mvn:org.pacesys.openstack4j.connectors/openstack4j-httpclient/${openstack4j-version}</bundle>
</feature>
</features>
But it does not solve my problem.
How can I use OpenStack4j in my OSGi environment?
EDIT:
I have discovered that the NullPointerException is caused by a bug in the code (here the issue). It has been fixed.
Anyway, the issue with SPI persist.

I fear there is no simple solution for your issue. Regarding to the sources, the HttpExecutor is looking for a HttpExecutorService via the ServiceLoader. This most likely doesn't work as the ServiceLoader doesn't know anything about BundleClassloaders, and since your instantiating it from your Bundle it most likely is lacking the required package import. Another reason might be the ServiceLoader uses the parent classloader.
So you have three possibilities.
1) Make sure you are also importing org.openstack4j.core.transport.internal in your bundle
2) set the TCCL (Thread Context ClassLoader) to the classloader of the bundle containing the package. So the ServiceLoader is capable of finding it.
3) as Neil commented, use Aries SPY Fly ...

Related

Apache CXF SOAP JAXB issue on WebLogic 12c

We are using Java 8, Apache CXF as a SOAP client on top of Spring Boot to send SOAP messages to WS.
If the app is deployed as a WAR on Tomcat 8, the app works well and the SOAP client is sending the right XML messages with the right namespaces.
If the same app WAR is deployed on Weblogic 12c the SOAP message that is produced by the CXF SOAP client has missing namespaces.
We know that the WebLogic maybe uses some old JAXB jars that are responsible for creating the XML message from Java objects and they are different then the Tomcat server and this maybe the reason why we are seeing this issue.
We also know that we can specify in the weblogic.xml in the war file what jars the Weblogic needs to load from the war and what dependencies to load from directly from the Weblogic libraries, but every combination that we tried in the weblogic.xml does not work.
Any good advice will be fully appreciated
Sample XML output from Tomcat server with Apache CXF
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<event xmlns="http://www.test.com" xmlns:ns5="http://www.test2.com" xmlns:ns3="urn:test1:1423.15465:123123:namespace">
<ns5:created-date-time>2020-08-12T08:02:35Z</ns5:created-date-time>
<ns5:payload>
<Test2>
<ns3:ID>f14bb</ns3:ID>
<ns3:createdDateTime>2020-08-12T08:02:35Z</ns3:createdDateTime>
</Test2>
</ns5:payload>
</event>
</env:Body>
</env:Envelope>
Sample code from Weblogic 12c
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<event xmlns="http://www.test.com" xmlns:ns5="http://www.test2.com">
<ns5:created-date-time>2020-08-12T08:02:35Z</ns5:created-date-time>
<ns5:payload>
<Test2>
<ID>f14bb</ID>
<createdDateTime>2020-08-12T08:02:35Z</createdDateTime>
</Test2>
</ns5:payload>
</event>
</env:Body>
</env:Envelope>
The "urn:test1:1423.15465:123123:namespace" is completely ignored in the weblogic server making this XML message not valid by the consumer
weblogic.xml
we are trying to tell weblogic to load our classes from the war file instead of the JaxB classes from the web logic but without success
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>java.xml.bind.*</wls:package-name>
<wls:package-name>org.apache.cxf.*</wls:package-name>
<wls:package-name>javax.xml.ws.*</wls:package-name>
<wls:package-name>javax.wsdl.*</wls:package-name>
</wls:prefer-application-resources>
</wls:container-descriptor>
Except this issue everything else is working fine, the Apache CXF is sending correct in multiple scenarios, just in one is it not adding the namespace we need
It looks like you are describing a class loading problem here. Thus, kindly use the below tag in your weblogic.xml descriptor.
<prefer-web-inf-classes>false</prefer-web-inf-classes>
Some years ago I was struggling with class loading issues because I was missing it. Below you have an example about this extracted from this blog.
If after applying this you still are facing issues with the class loader, you should install Classloader Analysis Tool (CAT) to get the class loader, which is loading the conflicting classes. In this blog you will have some instructions about how to use CAT.
Importantly, in this document Oracle states about this
Note that in order to use prefer-application-packages or prefer-application-resources, prefer-web-inf-classes must be set to false.
This issue was solved by updating the package-info.java
#javax.xml.bind.annotation.XmlSchema(namespace = "urn:test1",
xmlns = {#XmlNs(prefix = "",
namespaceURI = "http://www.test.com")},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
This is the part of the package-info that was not been there before
xmlns = {#XmlNs(prefix = "",
namespaceURI = "http://www.test.com")}
adding the namespace trick JavaXB to add the original namespace
Please check the mentioned page, which has a different Filtering classloading:
<wls:prefer-application-packages>
<wls:package-name>com.ctc.wstx.*</wls:package-name>
<wls:package-name>javax.wsdl.*</wls:package-name>
<wls:package-name>org.apache.cxf.*</wls:package-name>
<!-- <wls:package-name>javax.jws.*</wls:package-name> -->
</wls:prefer-application-packages>

.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory

I am upgrading Weblogic server from 9 to 10.3.6. when I am trying to deploy my ear application and got below exception.
Caused By: java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory
at javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:123)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.createDocumentBuilderFactory(DefaultDocumentLoader.java:89)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:70)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:113)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:80)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:423)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:353)
at org.springframework.context.access.ContextSingletonBeanFactoryLocator.initializeDefinition(ContextSingletonBeanFactoryLocator.java:141)
at org.springframework.beans.factory.access.SingletonBeanFactoryLocator.useBeanFactory(SingletonBeanFactoryLocator.java:384)
at org.springframework.web.context.ContextLoader.loadParentContext(ContextLoader.java:341)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:195)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:481)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:181)
at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1868)
I tried all sorts for things including adding a weblogic-application.xml but it still does not work.
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application>
<xml>
<parser-factory>
<saxparser-factory>
org.apache.xerces.jaxp.SAXParserFactoryImpl
</saxparser-factory>
<document-builder-factory>
org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
</document-builder-factory>
<transformer-factory>
org.apache.xalan.processor.TransformerFactoryImpl
</transformer-factory>
</parser-factory>
</xml>
<prefer-application-packages>
<package-name>org.apache.xerces.parsers.*</package-name>
</prefer-application-packages>
</weblogic-application>
my weblogic.xml has
<prefer-web-inf-classes>true</prefer-web-inf-classes>
This is part of my pom.xml:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.8.1</version>
<scope>runtime</scope>
</dependency>
Please help. Thanks!
I answer my own question:
Below link inspired me of fixing this issue:
Dealing with "Xerces hell" in Java/Maven?
Basiclly I have removed all the dependencies of xml-api and xmlParserAPIs in pom.xml. The problem is fixed. The root cause is my classpath should not include any javax libraries which cause the library conflict with Weblogic app server. Hope it helps.
I had the similar problem. I was using an application installed on wildly server. The problem was that I have to place xerces jars in both framework's and third party lib folder of the application. After much research, I found the solution in the documentation of xerces.
Why do I get a ClassCastException when I use Xerces and WebSphere Application Server?
Xerces uses the ObjectFactory class to load some classes dynamically, e.g. the parser configuration. The ObjectFactory finds the specified implementation class by querying the system property, reading META-INF/services/factoryId file or using a fallback classname. After the implementation is found, the ObjectFactory tries to load the file using the context classloader and if it is null, the ObjectFactory uses the system classloader.
If you run Xerces in an environment, such as WebSphere® Application Server, that has multiple classloaders you may get ClassCastExceptions thrown from Xerces because different classloaders might get involved in loading Xerces classes. For example, ClassCastExceptions may occur when utility EAR classes that use Xerces load Xerces classes from WAR modules.
We suggest you read the "Avoiding ClassCastExceptions..." article which explains a workaround for this problem. Also you might want to read the "J2EE Class Loading Demystified" article that explains how multiple classloaders work in WebSphere Application Server.
"
Basically, use two util class to create domparser object. For the service call from your application, change the classloader and create the object. After doing the processing, revert back the classloader.
ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader currentClassLoader = this.getClass().getClassLoader() ;
Thread.currentThread().setContextClassLoader(currentClassLoader);
//do the processing, after that revert back
https://xerces.apache.org/xerces2-j/faq-general.html

Worklight 6.0 does not start on Liberty - HSQLDB

I have followed the infocenter docs to setup Worklight on Liberty and Oracle Database all on Windows 2008.
(http://pic.dhe.ibm.com/infocenter/wrklight/v6r0m0/topic/com.ibm.worklight.help.doc/devref/t_transporting_apps_and_adapters.html - Deploying IBM Worklight applications to test and production environments)
When I start the liberty server, I get this error on the browser
Exception thrown by application class 'com.worklight.core.auth.impl.AuthenticationFilter.doFilter:110'
javax.servlet.ServletException: Worklight Project not initialized
at com.worklight.core.auth.impl.AuthenticationFilter.doFilter(AuthenticationFilter.java:110)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194)
at [internal classes]
Going thru the logs, it shows it did not start because the HSQLDB driver is not found.
The server.xml has the following:
<application id="finance" name="finance" location="finance.war" type="war">
<classloader delegation="parentLast">
<commonLibrary>
<fileset dir="${shared.resource.dir}/worklight/lib" includes="worklight-jee-library.jar"/>
</commonLibrary>
</classloader>
</application>
<library id="worklight/OracleLib">
<fileset dir="${shared.resource.dir}/worklight/oracle" includes="*.jar"/>
</library>
<!-- Declare the IBM Worklight Console database. -->
<dataSource jndiName="worklight/jdbc/WorklightDS" transactional="false">
<jdbcDriver libraryRef="worklight/OracleLib"/>
<properties.oracle driverType="thin" URL="jdbc:oracle:thin:#localhost:1521:ORCLWL" user="WORKLIGHTDIS" password="WORKLIGHTDIS"/>
</dataSource>
I took a step further and checked how the WAR file links to database jndi entries. Going thru the web.xml file I found this:
<resource-ref>
<description>Worklight Server Database</description>
<res-ref-name>jdbc/WorklightDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The res-ref-name is slightly different from what is declared in the server.xml. Bear in mind that these entries were created by the ant script. This seems to be inconsistent from what the war file contains (created by the WL Studio).
Anyway I gave it a try and changed the server.xml jndi entry to be exactly the same as the web.xml entry (jdbc/WorklightDS). When I restarted the liberty server It did not change the final result at all. The error message and the HSQL driver thing kept showing in the log.
This is the exception
nested exception is java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.hsqldb.jdbcDriver not found in Worklight platform or project /finance
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)
Later on I found out that if I change the element in the server.xml to be worklight value for all atributes it works. How odd it is.
<application id="worklight" name="worklight" location="finance.war" type="war">
Please, any help is much appreciated to help me understand and fix it.
The error message "java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.hsqldb.jdbcDriver not found in Worklight platform or project ..." is indeed misleading. It should better read something like "Worklight server cannot be started because no data-source is bound to resource reference: 'jdbc/WorklightDS'. Re-configuring the server will solve this problem. for more information search for "Creating and configuring the databases" in IBM Worklight information center."
The explanation for the error message is that by writing <application id="finance" name="finance" location="finance.war" type="war"> you selected a context root /finance, according to the WebSphere Liberty rules at Deploying a web application to the Liberty profile. For this context root, you need to write
<dataSource jndiName="finance/jdbc/WorklightDS" transactional="false">
This is similar to how JNDI environment entries need to be declared for Worklight (see here).

spring src-resolve issue "Cannot resolve the name ...''

I'm stuck with a standalone java application I'm maintaining, I'm really new with Maven. I use the copy dependencies, package plugins in command line and everything it's ok, but then when I see the project in eclipse, it validates the project and it seems that there is a problem checking which .xsd version should take into account.
Description Resource Path Location Type src-resolve: Cannot resolve
the name 'beans:identifiedType' to a(n) 'type definition'
component. spring-jee-2.0.xsd
Description Resource Path Location Type src-resolve: Cannot resolve
the name 'beans:identifiedType' to a(n) 'type definition'
component. spring-jee-2.5.xsd
I'm using spring 2.5.6 and I cannot upgrade. I do not know if I have to set up something in my eclipse IDE.
My configuration file is like this:
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
Any ideas or suggestions? Is it something related with a problem in the project or with eclipse IDE?
Thanks in advance
I cannot reproduce your situation, but it seems to be related to this problem:
That's a feature of STS (trying to be clever and importing XSD from
project classpath it fails to find the spring core ones). Raise a JIRA
ticket there if you want to really solve the problem, but my
understanding is that it is a compromise - users who do not edit
custom XSDs are far more numerous than those that do, so it's better
to support the larger group.
You can work around it by adding the spring-beans-3.1.xsd to your XML
Catalog in Eclipse (look in Preferences). You probably only need to
specify a namespace id, but I always add the schema location to be on
the safe side. You probably need to extract the XSD from the spring
jar file because I don't think you can add a catalog entry from a jar.
So, try to add spring-beans-2.5.xsd to XML Catalog in Eclipse. Hope this helps.

OC4J 10.1.3.5 / Spring3 Issue

I'm using OC4J 10.1.3.5.0, and have an issue with the XML namespaces in the Spring XML files supplied in the WAR/EAR.
According to the Oracle documentation, there is a known issue in parsing the Spring 3 XSD files within OC4J, as this embeds the Oracle XMLParserV2 jar and uses this for all XML parsing (which has issues with some XSD tricks used in Spring 3 apparently).
I've folowed the Oracle work-around, defining my own XML parser shared libraries on the OC4J instance, and (in the orion-application.xml), defining the shared library to use. I created a shared library,'apache.xml', with xercesImpl (v 2.9.1), xml-apis (v 1.3.04), and xml-resolver (v 1.2). I tried defining the EAR to use the new library
<imported-shared-libraries>
<imported-shared-library name="apache.xml"/>
</imported-shared-libraries>
I receive the following error
14:50:31 ERROR (UserId:) [DispatcherServlet] Context initialization failed
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
Line 10 in XML document from ServletContext resource [/WEB-INF/spring/webflow-config.xml] is invalid;
nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c:
The matching wildcard is strict, but no declaration can be found for element 'webflow:flow-executor'.
The webflow-config.xml file is defined as normal:
<?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:webflow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
<!-- Executes web flows -->
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
<!-- Rest of the file ... -->
</beans>
Does anyone have any ideas?
[Edit]
The snippet:
<imported-shared-libraries>
<imported-shared-library name="apache.xml"/>
</imported-shared-libraries>
should, of course read:
<imported-shared-libraries>
<import-shared-library name="apache.xml"/>
</imported-shared-libraries>
Sorry!
I found the answer to this. Turns out this was specifically because I was running OC4J on a Java 6 JVM. If anyone else gets this problem, here's what we did to resolve:
The Oracle XML parser does not handle the Spring 3 XSD files well, this is a know issue. You need to remove the Oracle XSD libraries for your application. In your orion-application.xml file, you need
<imported-shared-libraries>
<remove-inherited name="oracle.xml"/>
</imported-shared-libraries>
The Oracle documentation then tells you to import a new shared library. However, if you're running OC4J on a Java 6 JVM (which we are!), you can't do this. It looks like there is an XML parser in the Java 6 core now, and importing Xerces libraries will conflict with these classes, causing weird errors.
Anyway, on Java 6, remove the Oracle libraries, but don't import any other ones!

Resources