2
votes

I am trying to consume apache-cxf Web Services In Liferay-7 portlet ,I got the following error in linux environment.

13:39:14,374 ERROR [http-nio-4080-exec-9][status_jsp:950] com.liferay.portal.kernel.portlet.PortletContainerException: com.liferay.portal.kernel.portlet.PortletContainerException: javax.servlet.ServletException: java.lang.LinkageError: com/sun/org/apache/xpath/internal/jaxp/XPathImpl

If I run the same portlet in liferay 7 windows environment it is working fine

And here is the sample jsp code (view.jsp)

<portlet:defineObjects />
<%@ page import="org.apache.cxf.endpoint.Client" %>
<%@ page import="org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%

String endpoint="http://*******/***-ws/soap/login?wsdl";
String method ="login";
String uname ="admin";
String pwd = "admin";
String result = "";

Object[] params = new Object[2] ;
params[0] = (Object)uname;
params[1] = (Object)pwd;

result = call(endpoint, method, params);
System.out.println("Result : "+result);
%>
<%!

public static  String call(String endpoint, String method, Object[] params) {

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

try {
    Client client = dcf.createClient(endpoint);
    System.out.println("Client Object Create successfully  :");
    Object[]  returnVals = client.invoke(method, params);
    //extract returned value. getting 1st value as sakai ws calls returns only one value.
    if(returnVals!=null && returnVals.length>0)
        return (String)returnVals[0];
}
catch (Exception e) {
    e.printStackTrace();
    System.out.println("A connection error occurred: " + e.getClass() + ": " + e.getMessage());
}
return null;
}
%>

The Problem is occurring at Client client = dcf.createClient(endpoint);

Here is the dependencies we are using

==============================

cxf-core-3.1.8.jar

cxf-rt-bindings-soap-3.1.8.jar

cxf-rt-databinding-jaxb-3.1.8.jar

cxf-rt-frontend-jaxws-3.1.8.jar

cxf-rt-frontend-simple-3.1.8.jar

cxf-rt-transports-http-3.1.8.jar

cxf-rt-wsdl-3.1.8.jar

neethi-3.0.3.jar

==============================

Same Code I have checked in Liferay 6.2 and its working fine in both windows and linux environment, but I have added some more jar files.

==============================

cxf-rt-bindings-xml-3.1.8.jar

cxf-rt-ws-addr-3.1.8.jar

cxf-rt-ws-policy-3.1.8.jar

jaxb-impl-2.2.11.jar

jaxb-core-2.2.11.jar

xmlschema-core-2.2.1.jar

stax2-api-3.1.4.jar

woodstox-core-asl-4.4.1.jar

wsdl4j-1.6.3.jar

==============================

Please Help me out .

Thanks & Regards,

P.V.B.Raju.

2
How do you package your app? Do you use WARs? OSGi Bundles? Fat OSGi jars? - Miroslav Ligas
We are using plugin-portlet(WAR) - Venkata BangaruRaiu potnuru
Linux and windows load the lib in different order maybe there is a required sequence in which the libraries need to be loaded to make it work. This could be caused by having too many implementations on the classpath and things get overridden. Also, I would consider the OSGi approach in developing plugins. - Miroslav Ligas
we tried to implement the same thing in modular approach, - Venkata BangaruRaiu potnuru
could you paste the Gradle/maven file in here with the dep definitions? - Miroslav Ligas

2 Answers

1
votes

I tried the war approach and it worked fine. I tested in on Liferay 7 DXP FP 32.

See my test code. https://github.com/mir333/cxf-test-demo

The jar approach is a bit more tricky because you need to list all necessary libraries in Gradle and bnd file. Basically, everything that is in the war files lib folder would need to be inserted there and if you get still a missing import message you need to find a lib that provides the package and add it as well.

Have a look at this blog post it explains how to do it and it refers to another blog post have a look at it also. https://web.liferay.com/web/sushil.patidar/blog/-/blogs/liferay-osgi-module-project-dependency-resolution

EDIT: New tooling becomes available for this. Have a look at https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/adding-third-party-libraries-to-a-module#embedding-libraries-using-gradle make sure you are on the right Gradle plugin.

1
votes

My approach was different. I installed the necessary Apache CXF modules as an OSGi bundle on the Liferay instance, after which I built a simple WS client using the CXF APIs exported to the OSGi container. Apache CXF modules installed as OSGIi bundle.

  • Apache XmlSchema Core (v. 2.2.1)
  • Apache CXF Core
  • Apache CXF Runtime JAXB DataBinding
  • Apache CXF Runtime XML Binding
  • Apache CXF Runtime SOAP Binding
  • Apache CXF Runtime Core for WSDL
  • Apache CXF Runtime Simple Frontend
  • Apache CXF Runtime JAX-WS Frontend
  • Apache CXF Runtime HTTP Transport

The installation of the nine elements of the Apache CXF framework can be performed by connecting via telnet to the Apache Felix GoGo Shell. Once the Liferay 7 portal is running, the Apache CXF framework can be installed by executing the commands install $URL_CXF_BUNDLE

For more information you can read this article Liferay 7: Come realizzare un client SOAP con Apache CXF in OSGi Style