Webservice Plugin not working

Hi, in Servoy in want to call a webservice which uses complex types. So using the dynamic webservices pluginis no option for me.
Now I Created a plugin in Netbeans which contains the client that consumes the webservices. I generated the client based on the WDSL file of the service.

Now when I run this client in Netbeans, the call to the server goes all fine. But when I use servoy and call the webservice with the plugin, Servoy just ‘hangs’. I don’t get an errormessage, but the application also doesn’t continue?

Anyone here (who has experience with Webservice ) who knows what I can be doing wrong?

ClientPlugin code:

package com.clientplugin;
import java.util.Properties;

import com.servoy.j2db.plugins.IClientPlugin;
import com.servoy.j2db.plugins.IClientPluginAccess;
import com.servoy.j2db.plugins.PluginException;
import com.servoy.j2db.preference.PreferencePanel;
import com.servoy.j2db.scripting.IScriptObject;

import etrade.webservice.GetSupplyResponse;
import java.beans.PropertyChangeEvent;
import javax.swing.Icon;
import javax.swing.ImageIcon;

public class ClientPlugin implements IClientPlugin {

    private IClientPluginAccess access;
    private ClientPluginProvider scriptObject;

    public Icon getImage() {
        return null;
    }

    public String getName() {
       return "EtradeClientPlugin";
    }

    public PreferencePanel[] getPreferencePanels() {
        return null;
    }

    public IScriptObject getScriptObject() {
        if(scriptObject == null)
        {
            scriptObject = new ClientPluginProvider();

        }

        return scriptObject;
    }

    public void initialize(IClientPluginAccess arg0) throws PluginException {
        access = arg0;    


    }

    IClientPluginAccess getClientPluginAccess()
    {
            return access;
    }

    public void load() throws PluginException
    {
    }

	public void unload() throws PluginException
	{
		access = null;
                scriptObject = null;

	}

	public Properties getProperties()
	{
                Properties props = new Properties();
		props.put(DISPLAY_NAME, "ETrade Client"); //$NON-NLS-1$
		return props;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent evt)
	{
		// ignore
	}

}

ClientProvider code, which calls the ‘web.CallService’ which works when I tested it in Java.

import com.servoy.j2db.scripting.IScriptObject;
import etrade.webservice.GetSupplyResponse;
import etrade.webservice.GetSupply.SupplyRequest;
import etrade.webservice.SupplyResponse;

/**
 *
 * @author josj
 */
public class ClientPluginProvider implements IScriptObject
{
    public GetSupplyResponse.Return js_supplyRequest(int productID)
    {
        CallWebservice web = new CallWebservice();
        return web.CallService(productID);
    }

    public String js_getName()
    {
        return "Jos Janssen";

    }

    public String js_webCall(int productID)
    {
        CallWebservice web = new CallWebservice();
        GetSupplyResponse.Return ret = web.CallService(productID);

        if(ret.getErrormessage().equals("") )
        {
            return "Success";
        }else
        {
            return ret.getErrormessage();
        }

        //return "";
    }    

    public Class[] getAllReturnedTypes() {
        return new Class[] { GetSupplyResponse.Return.class };
    }

    public String[] getParameterNames(String methodName) {
        if (methodName == null)
            return null;

		if ("supplyRequest".equals(methodName)) //$NON-NLS-1$
		{
                    return new String[] {"productId"};             

                }
            if ("webCall".equals(methodName)) //$NON-NLS-1$
		{
                    return new String[] {"productId"};

                }
        return null;
    }

    public String getSample(String arg0) {
        return "var result = %%elementName%%.supplyRequest(1)";
    }

    public String getToolTip(String arg0) {
        return "Etrade Client implementation";
    }

    public boolean isDeprecated(String arg0) {
        return false;
    }

}

Thanks.

Hi Janssenjos!

The first thing that comes to mind from the look of your code is that you refer to a package “etrade.webservice.*” in the plugin code, did you put the relevant jar library in a subfolder of /plugins and made a jnlp so that Servoy Smart client can load it properly?

Also, you are doing synchronous calls to the web service, that’s bad!
I would think that it can hang Servoy (no UI update can take place during the call, which can be lengthy, so even if it works it can hang Servoy for good!).

What I would do is make the call asynchronous, by launching a Thread and returning immediately to Servoy and when receiving the WebService response, call back a Servoy method with the result…

To be able to callback Servoy’s javascript method, you need to add a parameter (String methodName), which can take the form: “myMethod”, or “form1.myMethod” or “globals.myMethod”, you also need to give access to the IClientPluginAccess to the IScriptObject (pass it as a parameter in the constructor of your ClientPluginProvider), because you will need it to call its executeMethod. Then you can use the kind of code I use in the attached ServoyUtils class to callback your method when your web service has returned a response.

Also I don’t know the type of your “GetSupplyResponse.Return” class but it could be a problem if it is not serializable. In any case, I wouldn’t return it directly to Servoy’s scripting, I would rather create a wrapper class with relevant fields, make it Serializable and implementing IScriptObject too so that users will be able to script it in JavaScript properly.

Hope this helps!

ServoyUtils.zip (1.57 KB)

Hi ptalbot,
thanks for the reply.

About the package “etrade.webservice”, this package is included in my clientplugin jar library(same as the com.clientplugin package) that is in the plugins folder. Could that be a problem, that it perhaps should be in a seperate jar library?

I will look into the asynchronous solution, but I don’t think that is the problem right now, cause a call to the same webservice from a Java Client is very fast.
Also about the serialization, I also used the call ‘js_webCall’ in my servoy client, which returns a String, and I have the same problem there. So I also don’t think the problem is here.

But thanks for the async example, I will take a look at that for sure.

Janssenjos:
About the package “etrade.webservice”, this package is included in my clientplugin jar library(same as the com.clientplugin package) that is in the plugins folder. Could that be a problem, that it perhaps should be in a seperate jar library?

No, but this package itself must have dependencies (to Apache Axis probably?), so you will need to add the required jar into the plugins folder as well (in a subfolder), and create a jnlp to tell the smart client to download them as well.

When you say that the call from Netbeans works but then deployed in Servoy it doesn’t, it really look like a dependency problem.
Perhaps you could add some Debug.log() or Debug.error() in a try catch statement of your call to see if there are some Exceptions…

Janssenjos:
I will look into the asynchronous solution, but I don’t think that is the problem right now, cause a call to the same webservice from a Java Client is very fast.

Remember that what seems very fast to you can be an eternity to the Swing UI eventDispatch and update Thread ;-)

I’ve used jax-ws(I believe) to generate the webservice client in Java. So I guess I have to add those jars in a subfolder, I’m going to try that right now.

I Think I made a mistake in my plugin code, cause I built a new plugin today, and this one works. So the problem is solved.

Now I have another issue I am facing:

I made the plugin, so the method webCall requires a ‘request’ object as parameter. but now I can’t find anywhere how to use my own java class in Servoy.
I can instantiate a package from J2SE like this: ‘var pack = Packages.java.io’, but when I use my own namespace from the plugin it can’t be found by Servoy. So the question is, what do I have to do so I can import my own packages? (Place the lib somewhere, something in the options?)

Ok, succeeded to import the package, but now having another problem with this: :roll:

Getting an errormessage:

Java constructor for "data.SupplyResponse$Body" with arguments "" not found.

My Java Object is as followed:

package com.data;

public class SupplyResponse
{
    public SupplyResponse.Body body;

    public class Body //Multiple classes which contains Body
    {
        public Body()
        {
        
        }
        
        public String supplyName;
        public String supplyQuantity;
    }
    
}

And my Servoy code is:

var data = Packages.com.data;
	
var response = data.SupplyResponse(); //this works
	
//goes wrong here.
response.body = data.SupplyResponse.Body();
response.body.supplyName = "Test";

Shouldn’t this work?

It’s up to Rhino to answer that one ;-)

In your code, I think you are not creating an instance there:

response.body = data.SupplyResponse.Body();

So response.body will be null!

I believe you should use:

response.body = new data.SupplyResponse.Body();

Maybe you could add this kind of code inside your SupplyResponse class:

public Body getBodyInstance() {
    return new Body();
}

Probably making Body() a singleton would be better.
And adding some getter/setter methods would be cleaner (you are breaking encapsulation here, bad mojo in the future, I tell you!). Now that I’ve said that I just realize that maybe Rhino is probably looking for them…

Now you can call it like that:

var data = Packages.com.data;

var response = new data.SupplyResponse(); //this works

//goes wrong here.
response.body = response.getBodyInstance();
response.body.supplyName = "Test";

Hope this helps,

Hi, Thanks for the help. Making the getInstance is one solution that works, and getter/setters I’m going to make after the testing. (Just a bit lazy now).

Last thing left(Hopefully) for me are the errors of the headless client and the java webservice.