PeerUnavailableException using JAIN SIP API on Android - java

I'm trying to build SIP application using JAIN SIP 1.2 and the NIST implementation on android.
I have rebuilt jain-sip-api-1.2.jar and jain-sip-ri-1.2.1111.jar from source, and renamed javax -> jain_javax and gov.nist.javax -> jain_gov.nist.jain_javax. I tested the jar files on textclient example on standard java without problem. However, when I run it on Android I still get the error:
"The Peer SIP Stack: jain_gov.nist.jain_javax.sip.SipstackImpl could not be instantiated. Ensure the Path Name has been set".
Did I miss anything here?

It is not sufficient to rename the packages. JAIN-SIP has internal references to some classes by their original package name "gov.nist". You should also double check all your code to rename any "gov.nist" references such as the prefix for the stack classes.
Android has built-in an older version of JAIN-SIP which is taking over some of the existing references to those "gov.nist" classes. It's not an exported API, so not quite obvious. That's why it may behave differently on desktop machines. Post you code and full error messages/debug logs if you need more help.

Sovled. Jain Sip is using log4i-1.2.x.jar which does not work properly on Android. There are lots of discussion on Internet how to make log4j working on Android but none of them works for me. I have removed all log4j related code from Jain Sip source and now the sip stack is working properly on Android.

I am using JAIN-SIP-1-2-164. Here is the app code:
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.text.ParseException;
import java.util.*;
import android.os.Handler;
import jain_javax.sip.*;
import jain_javax.sip.address.*;
import jain_javax.sip.header.*;
import jain_javax.sip.message.*;
public class SipLayer implements SipListener {
private SipStack sipStack;
private SipFactory sipFactory;
private Properties properties;
private String local_ip;
int listen_port;
/** Here we initialize the SIP stack. */
public SipLayer(int listen_port) {
try {
setUsername(username);
this.local_ip = InetAddress.getLocalHost().getHostAddress();;
this.listen_port = listen_port;
// Create the SIP factory and set the path name.
this.sipFactory = SipFactory.getInstance();
this.sipFactory.setPathName("jain_gov.nist");
// Create and set the SIP stack properties.
this.properties = new Properties();
this.properties.setProperty("jain_javax.sip.STACK_NAME", "stack");
this.properties.setProperty("jain_javax.sip.IP_ADDRESS", local_ip);
if(proxy != null)
this.properties.setProperty("jain_javax.sip.OUTBOUND_PROXY", proxy + ':' + server_port + '/' + protocol);
//DEBUGGING: Information will go to files textclient.log and textclientdebug.log
this.properties.setProperty("jain_gov.nist.javax.sip.TRACE_LEVEL", "32");
// this.properties.setProperty("jain_gov.nist.javax.sip.SERVER_LOG", "textclient.txt");
// this.properties.setProperty("jain_gov.nist.javax.sip.DEBUG_LOG", "textclientdebug.log");
// Create the SIP stack.
this.sipStack = this.sipFactory.createSipStack(properties);
}
catch (Exception e) {
msgProc.processError("SipLayer failed: " + e.getMessage() + "\n");
}
}
}
Same code runs ok on java on a windows machine, but android emulator I got above mentioned error message.
I found that it failed in following Jain SIP 1.2 routine at "SipStack sipStack = (SipStack) sipStackConstructor.newInstance(conArgs);"
private SipStack createStack(Properties properties)
throws PeerUnavailableException {
try {
// create parameters argument to identify constructor
Class[] paramTypes = new Class[1];
paramTypes[0] = Class.forName("java.util.Properties");
// get constructor of SipStack in order to instantiate
Constructor sipStackConstructor = Class.forName(
getPathName() + ".jain_javax.sip.SipStackImpl").getConstructor(
paramTypes);
// Wrap properties object in order to pass to constructor of
// SipSatck
Object[] conArgs = new Object[1];
conArgs[0] = properties;
// Creates a new instance of SipStack Class with the supplied
// properties.
SipStack sipStack = (SipStack) sipStackConstructor.newInstance(conArgs);
sipStackList.add(sipStack);
String name = properties.getProperty("jain_javax.sip.STACK_NAME");
this.sipStackByName.put(name, sipStack);
return sipStack;
} catch (Exception e) {
String errmsg = "The Peer SIP Stack: "
+ getPathName()
+ ".jain_javax.sip.SipStackImpl"
+ " could not be instantiated. Ensure the Path Name has been set.";
throw new PeerUnavailableException(errmsg, e);
}
}
Any suggestion or how to debug further?

Related

Javamail - Why can't I get it to work?

I stole this code to test about emailing using java. Javamail is required, obviously. For some reason, I can't get javax.mail to implement. I downloaded the most recent javamail and put them in the jdk and jre lib folders, yet nothing changes. Please and thank you!
//A class which uses this file to send an email :
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* Simple demonstration of using the javax.mail API.
*
* Run from the command line. Please edit the implementation
* to use correct email addresses and host name.
*/
public final class Emailer {
public static void main( String... aArguments ){
Emailer emailer = new Emailer();
//the domains of these email addresses should be valid,
//or the example will fail:
emailer.sendEmail(
"sean_chili#yahoo.com", "clevelanm#sou.edu",
"Testing 1-2-3", "blah blah blah"
);
}
/**
* Send a single email.
*/
public void sendEmail(
String aFromEmailAddr, String aToEmailAddr,
String aSubject, String aBody
){
//Here, no Authenticator argument is used (it is null).
//Authenticators are used to prompt the user for user
//name and password.
Session session = Session.getDefaultInstance( fMailServerConfig, null );
MimeMessage message = new MimeMessage( session );
try {
//the "from" address may be set in code, or set in the
//config file under "mail.from" ; here, the latter style is used
//message.setFrom( new InternetAddress(aFromEmailAddr) );
message.addRecipient(
Message.RecipientType.TO, new InternetAddress(aToEmailAddr)
);
message.setSubject( aSubject );
message.setText( aBody );
Transport.send( message );
}
catch (MessagingException ex){
System.err.println("Cannot send email. " + ex);
}
}
/**
* Allows the config to be refreshed at runtime, instead of
* requiring a restart.
*/
public static void refreshConfig() {
fMailServerConfig.clear();
fetchConfig();
}
// PRIVATE //
private static Properties fMailServerConfig = new Properties();
static {
fetchConfig();
}
/**
* Open a specific text file containing mail server
* parameters, and populate a corresponding Properties object.
*/
private static void fetchConfig() {
InputStream input = null;
try {
//If possible, one should try to avoid hard-coding a path in this
//manner; in a web application, one should place such a file in
//WEB-INF, and access it using ServletContext.getResourceAsStream.
//Another alternative is Class.getResourceAsStream.
//This file contains the javax.mail config properties mentioned above.
input = new FileInputStream( "C:\\Temp\\MyMailServer.txt" );
fMailServerConfig.load( input );
}
catch ( IOException ex ){
System.err.println("Cannot open and load mail server properties file.");
}
finally {
try {
if ( input != null ) input.close();
}
catch ( IOException ex ){
System.err.println( "Cannot close mail server properties file." );
}
}
}
}
Just for completeness, here's the answer.
Your Eclipse is telling you
<Some Class> cannot be resolved to a type
This is usually an indication that your classpath is not correct. You said
I downloaded the most recent javamail and put them in the jdk and jre
lib folders, yet nothing changes
Don't do this. Take the javamail.jar and use it on your application Build Path. To do so, drag and drop the jar into your project, right-click it and select Build Path > Add to build path.

JavaAgent in Lotus Notes 6.5 using axis api gives Exception "No implementation defined for org.apache.commons.logging.LogFactory"

I needed to write a JavaAgent in a Lotus Notes 6.5 DB to access a web service. I used Axis Apache API for this purpose. I created A Java agent and added the jar files of axis in the agent by using Edit Project button.
Below is the agent code:
import lotus.domino.*;
import javax.xml.*;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import java.net.URL;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
String endpoint = "http://ws.apache.org:5049/axis/services/echo";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/", "echoString"));
String ret = (String) call.invoke( new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
} catch(Exception e) {
e.printStackTrace();
}
}
}
And below is the exception thrown:
java.lang.ExceptionInInitializerError: org.apache.commons.discovery.DiscoveryException: No implementation defined for org.apache.commons.logging.LogFactory
at org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface.java:197)
at org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:579)
at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:84)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:80)
at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:72)
at org.apache.axis.configuration.EngineConfigurationFactoryFinder.<clinit>(EngineConfigurationFactoryFinder.java:94)
at org.apache.axis.client.Service.<init>(Service.java:111)
at JavaAgent.NotesMain(JavaAgent.java:17)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(NotesThread.java:218)
I thried to follow some links on the internet like, But i was not able to get exactly what it was asking to do. eg: http://www-10.lotus.com/ldd/nd6forum.nsf/55c38d716d632d9b8525689b005ba1c0/40d033fba3897f4d85256cd30034026a?OpenDocument
Any help will be great. All i wanted to do is write an agent so that i can access a web service, say temperature conversion web service on w3schools. http://www.w3schools.com/webservices/tempconvert.asmx?op=FahrenheitToCelsius
I googled with your error message and this is the first hit:
http://croarkin.blogspot.fi/2010/08/commons-logging-headaches-with-axis.html
It suggests using a commons-logging.properties file with:
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger
org.apache.commons.logging.LogFactory = org.apache.commons.logging.impl.LogFactoryImpl
or putting this to your code:
#BeforeClass
public static void beforeClass() {
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Log4JLogger");
System.setProperty("org.apache.commons.logging.LogFactory", "org.apache.commons.logging.impl.LogFactoryImpl");
}
Probably you've already tried this because it's the first hit with google but just in case...

FTP exception 501 "pathname" more than 8 characters

I am trying to access a file via a URI using the FTP protocol. For obvious security reasons I had to make some changes but this is where the problems seem to be coming from.
My URI is as follows:
ftp://user:pasword#host.net/u/Bigpathname/XYZ/ABC/BigPathname/bigpathname/xyz/abc/MY_LOG.LOG
And I see this exception:
sun.net.ftp.FtpProtocolException: CWD Bigpathname:501 A qualifier in "Bigpathname" is more than 8 characters
This is really confusing as I can access the file from a Windows 7 command line with the CD command just fine. Both one directory at a time and as a full path.
I found one article mentioning that MVS file names must be 8 or fewer characters but this does not explain how I can get to these same files from my command line! They do exist there is data there that I can download manual but I can not get there via a URI in Java.
PS I use .toURL().openStream() to get files on my local machine just fine, it only fails when I try to get them from my server.
EDIT October 1st
I am able to access files on the MVS host using FileZilla and the basic FTP client from the Windows 7 command line - but I still cannot get them from a URI/URL. I downloaded a very basic Java built FTP client and tried accessing the same file in my program from there and the path works but because my file name has a dot in it "MY_LOG.LOG" I am getting File does not exist 501 Invalid data set name "MY_LOG.LOG". Use MVS Dsname conventions. I am utterly perplexed by this...
EDIT Ocotober 1st afternoon :)
OK I finally got it to work with a FTP client in my Java code - but I still want to use the URL class as I have logs on both local and remote machines. Is there a way to encode a URL string so that it can retrieve a file from a remote machine with the FTP protocol? I am not sure how it works in the Java URL class but in the FTP client I had to use the CWD and then the RETR command.
If I can do this then I have one solution for getting all my logs, otherwise I will have to detect if it is a file or ftp URL and then behave differently. Not the end of the world but not what I want...
The code that tries to get the file with just a URL is as follows: (sysc is a valid host)
void testFTP()
{
String ftp = "ftp://user:pword#sysc/u/Xxxxxxxxxx/ICS/YT7/XxxxxXxxxxxxx/xxxxxxxxx/logs/xxxxxxxx/XX_YT.LOG";
try
{
URI uri = new URI(ftp);
URL ftpFile = uri.toURL();
BufferedReader in = new BufferedReader(new InputStreamReader(ftpFile.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
In this case I think the problem is also Server Related, It all works fine for me with Filezilla Server except when the filename length(including directories) exceeds 255 chars but if you want to use the URL class with another FTP you must override or implement your own URLStreamHandlerFactory.
URL.setURLStreamHandlerFactory(...);
I haven't found any for my favorite java FTP Client witch is Apache one so I have developed one but may need a few touch ups.
package net.custom.streamhandler.apacheftp;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
public class ApacheURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
//this will only override the chosen protocol
if ( protocol.equalsIgnoreCase("ftp") )
return new CustomHandler();
else
return null;
}
}
class CustomHandler extends URLStreamHandler {
protected URLConnection openConnection(URL url)
throws IOException {
return new CustomURLConnection(url);
}
}
class CustomURLConnection extends URLConnection {
int reply;
FTPClient ftp = new FTPClient();
InputStream in;
static int defaultPort = 21;
static String defaultPath = "/";
CustomURLConnection ( URL url)
throws IOException {
super( url );
}
synchronized public void connect() throws IOException {
try {
int port;
if ((port = url.getPort()) == -1 )
port = defaultPort;
ftp.connect(url.getHost(), port);
String login = "anonymous";
String password = "";
if(url.getAuthority().indexOf(':')>-1 &&
url.getAuthority().indexOf('#')>-1){
String []auxArray = url.getAuthority().replaceAll("#", ":").split(":");
login = auxArray[0];
password = auxArray[1];
}
ftp.login(login, password);
reply = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
System.out.println("Connected Apache Success");
} else {
System.out.println("Connection Apache Failed");
ftp.disconnect();
}
in = ftp.retrieveFileStream(url.getFile());
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
connected = true;
}
synchronized public InputStream getInputStream()
throws IOException {
if (!connected)
connect();
return ( in );
}
}
*Keep in mind that you can implement new ways to handle different protocols for the java.net.URL this way.
Your code...
...
{
String ftp = "ftp://user:pword#sysc/u/Xxxxxxxxxx/ICS/YT7/XxxxxXxxxxxxx/xxxxxxxxx/logs/xxxxxxxx/XX_YT.LOG";
try
{
URL.setURLStreamHandlerFactory(new ApacheURLStreamHandlerFactory());
...
G'Bye
**(To err is human, to forgive is divine)
Try using the short name for the path. Something like /U/BIGPAT~1/XYZ/ABC/BIGPAT~1/BIGPAT~1/XYZ/ABC/MY_LOG.LOG
You can find the short name for any directory longer than 8 characters with dir /x.
FTP clients are notoriously difficult to write given the variation of (and bugs in) server implementations.
I'm betting that MVS is not completely supported by sun.net.ftp.FtpClient, which is the class used under the hood when you call URL.openStream on an FTP URL.
The Apache Commons Net library should support MVS, but it sounds like you already found a working client.
Have you considered using an RMI for transporting the files that way you can give a direct path to the file as a parameter without the use of ftp then have the file sent back in a byte array.

How do you implement a ManagedServiceFactory in OSGi?

Im currently trying to setup my own implementation of a ManagedServiceFactory. Here is what I'm trying to do: I need multiple instances of some service on a per-configuration base. With DS the components worked perfectly but now I found out that these services should handle there own lifecycle (i.e. (de)registration at the service registry) depending on the availability of some external resource, which is impossible with DS.
Thus my idea was to create a ManagedServiceFactory, which then would receive configs from the ConfigurationAdmin and create instances of my class. These again would try to connect to the resource in a seperate thread and register themselves as service when they're ready to operate.
Since I had no luck implementing this yet, I tried to break everything down to the most basic parts, not even dealing with the dynamic (de)registration, just trying to get the ManagedServiceFacotry to work:
package my.project.factory;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
public class Factory implements BundleActivator, ManagedServiceFactory {
private ServiceRegistration myReg;
private BundleContext ctx;
private Map<String, ServiceRegistration> services;
#Override
public void start(BundleContext context) throws Exception {
System.out.println("starting factory...");
this.ctx = context;
java.util.Dictionary properties = new Hashtable<String, Object>();
properties.put(Constants.SERVICE_PID, "my.project.servicefactory");
myReg = context.registerService(ManagedServiceFactory.class, this,
properties);
System.out.println("registered as ManagedServiceFactory");
services = new HashMap<String, ServiceRegistration>();
}
#Override
public void stop(BundleContext context) throws Exception {
for(ServiceRegistration reg : services.values()) {
System.out.println("deregister " + reg);
reg.unregister();
}
if(myReg != null) {
myReg.unregister();
} else {
System.out.println("my service registration as already null " +
"(although it shouldn't)!");
}
}
#Override
public String getName() {
System.out.println("returning facotry name");
return "ServiceFactory";
}
#Override
public void updated(String pid, Dictionary properties)
throws ConfigurationException {
System.out.println("retrieved update for pid " + pid);
ServiceRegistration reg = services.get(pid);
if (reg == null) {
services.put(pid, ctx.registerService(ServiceInterface.class,
new Service(), properties));
} else {
// i should do some update here
}
}
#Override
public void deleted(String pid) {
ServiceRegistration reg = services.get(pid);
if (reg != null) {
reg.unregister();
}
}
}
Now, it should receive configurations from the ConfigurationAdmin for PID my.project.servicefactory, shouldn't it?
But it does not receive any configurations from the ConfigurationAdmin. The bundle is started, the service is registered and in the web console, I can see the config admin holds a reference to my ManagedServiceFactory. Is there a certain property which should be set? The interface specification does not suggest that. Actually my implementation is more or less the same as the example there. I've no idea what I'm doing wrong here, any pointers to the solutions are very welcome.
Also, I orginally thought to implement the ManagedServiceFactory itself as DS, which also should be possible, but I failed at the same point: no configurations are handed over by the ConfigAdmin.
update
To clarify the question: I think that this is mainly an configuration problem. As I see it, I should be able to specify two PIDs for the factory, one which identifies a configuration for the factory itself (if any), and one which would produce services trough this factory, which I thought should be the factory.pid. But the framework constants do not hold anything like this.
update 2
After searching a bit the Felix Fileinstall source code, I found out that it treats configuration files differently when there is a - in the filename or not. Having the configuration file named my.project.servicefactory.cfg it did not work, but the configs named my.project.servicefactory-foo.cfg and my.project.servicefactory-bar.cfg were properly handed over to my ManagedServiceFactory as expected, and multiple services with ServiceInterface were registered. Hurray!
update 3
As proposed by Neil, I put the declarative service part in a new question to bound the scope of this one.
I think that the problem is you have a singleton configuration record rather than a factory record. You need to call Config Admin with the createFactoryConfiguration method using my.project.servicefactory as the factoryPid.
If you are using Apache Felix FileInstall (which is a nice easy way to create config records without writing code) then you need to create a file called my.project.servicefactory-1.cfg in the load directory. You can create further configurations with the same factoryPID by calling them my.project.servicefactory-2.cfg etc.

running an axis2 client version 1.5

So I'm running out of ideas to try to actually get a client to connect to the SOAP service I'm running through axis2.
I tried two methods, one was to use wsdl2java to build the stub and associated client side classes, and then write a Client class that build the requests messages and sends them through the Stub. The other way was to use the ServiceClient to connect..
Both are failing in their own way..
Option #1, every time a message is sent through the stub I get this back:
org.apache.axis2.AxisFault: The input stream for an incoming message is null.
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:87)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:67)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:354)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:417)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
Option #2, everytime I run it I get this Exception:
org.apache.axis2.deployment.DeploymentException: org.apache.axis2.transport.local.LocalTransportSender
Option #2 source:
import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;
public class loyaltyClient {
private static EndpointReference targetEPR =
new EndpointReference(
"http://localhost:8080/axis2/services/service");
public static OMElement verifyCustomer(String customer_id) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://localhost/", "service");
OMElement method = fac.createOMElement("VerifyCustomer", omNs);
OMElement value1 = fac.createOMElement("customer_id",omNs);
OMElement value2 = fac.createOMElement("source_id",omNs);
OMElement value3 = fac.createOMElement("source_password",omNs);
OMElement value4 = fac.createOMElement("source_txnid",omNs);
OMElement value5 = fac.createOMElement("timestamp",omNs);
value1.addChild(fac.createOMText(value1, customer_id));
value2.addChild(fac.createOMText(value2, "source"));
value3.addChild(fac.createOMText(value3, "1234"));
value4.addChild(fac.createOMText(value4, "123"));
value5.addChild(fac.createOMText(value5, "06-01-2010 12:01:01"));
method.addChild(value1);
method.addChild(value2);
method.addChild(value3);
method.addChild(value4);
method.addChild(value5);
return method;
}
public static void main(String[] args) {
try {
OMElement vctest = loyaltyClient.verifyCustomer("6177740603");
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(vctest);
String response = result.getFirstElement().getText();
System.out.println(response);
} catch (Exception e) { //(XMLStreamException e) {
System.out.println(e.toString());
}
}
}
I've also encountered the error "The input stream for an incoming message is null" while using Axis to connect to a .Net service provider.
The problem is that .Net doesn't not support a feature called "chunked encoding", by default Axis will break its request header in chunks which is suppose to be a HTTP 1.1 compliant thing.
Anyway, you can turn this feature off in Axis by doing the following:
// Turn off the Axsis Chunked feature, some service providers (like .Net) don't support chunked headers.
Options options = serviceClient.getOptions();
options.setProperty(HTTPConstants.CHUNKED, Constants.VALUE_FALSE);
serviceClient.setOptions(options);
This worked for me. Another thing to make sure of when dealing with .Net services is to be able to specify the port name and make sure your message payload has the namespace prefix for each element.
Hope this info helps somebody.
Cheers,
DC
With the caveat that Axis2 is a buggy pile of crap, I recently had to write an Axis2 client, and found that using the default ServiceClient() constructor didn't work well -- I had to manually create a ConfigurationContext, etc. I found that using ServiceClient.getOptions() instead of creating new Options() preserved some default data. I'd also recommend dropping the options.setTransportInProtocol(...) unless you really need it -- everything should work fine via HTTP without this. Also, you may need to set options.setAction(...) to correspond with the "operation" in your WSDL.
I've included the bulk of my client (with sensitive information stripped out), in hopes that it will help. You can probably safely ignore the portions regarding addressing unless you plan to use WS-Addressing.
ConfigurationContext cfgCtx = null;
try {
/* Passing null to both params causes an AxisConfiguration to be created that uses
* the default axis2.xml file, which is included in the axis2 distribution jar.
* This is ideal for our case, since we cannot pass a full file path (relative
* paths are not allowed) because we do not know where the customer will deploy
* the application. This also allows engaging modules from the classpath. */
cfgCtx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null , null);
} catch (AxisFault e) {
// Bubble up the error
}
ServiceClient svcClient = null;
try {
svcClient = new ServiceClient(cfgCtx, null);
} catch (AxisFault e) {
// Bubble up the error
}
try {
/* This will work with the above ConfigurationContext as long as the module
* (addressing-1.5.1.mar) is on the classpath, e.g. in shared/lib. */
svcClient.engageModule("addressing");
} catch (AxisFault e) {
// Bubble up the error
}
Options opts = svcClient.getOptions();
opts.setTo(new EndpointReference("http://myservername:8080/axis2/services/MyService"));
opts.setAction("urn:doSomething"); // Corresponds to the "operation" in MyService's WSDL
opts.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); // Set output to SOAP 1.2
SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
svcClient.addHeader(createSOAPSecurityHeader(factory, response)); // CreateSOAPHeader just creates an OMElement
try {
svcClient.sendReceive(createSOAPBody(factory, response)); // CreateSOAPBody just creates an OMElement
} catch (AxisFault e) {
throw new ResponseDeliveryException(1, "Error sending SOAP payload.", e);
}

Categories

Resources