I'm new I need your help, and I hope to be helpful in future.
When I try to create a web service starting from Java class
public class AddOperation {
public int add(int a, int b){
return a+b;
}
}
with Tomcat 6 Eclipse Helios Axis2 1.6.0 (eclipse plugin) at the time of generating the client and use it get
Eclipse Plugin creation Server
Eclipse Plugin creation Client
public class TestClient {
public static void testClientOperation() throws RemoteException{
AddOperationStub aos = new AddOperationStub();
Add add = new Add();
add.setA(2);
add.setB(3);
AddResponse addResponse = aos.add(add);
int result = addResponse.get_return();
System.out.println("Result is: "+result);
}
}
Instead, expect to have
public class TestClient {
public static void testClientOperation() throws RemoteException{
AddOperationStub aos = new AddOperationStub();
int result = aos.add(2, 3);
System.out.println("Result is: "+result);
}
}
where I'm wrong, because it creates the type Add?
Thanks to all.
By default Axis2 use doc/lit/wrapped style but what you have expected here is doc/lit/bare style, you need to add following property to services.xml file to generate bare service.
<parameter name="doclitBare" locked="false"> true</parameter>
If you have further issue write to user list http://axis.apache.org/axis2/java/core/mail-lists.html
Related
I am learning about webservices, and I've done a simple Calculator application using webservices, where the Calculator and its functions to perform the operations are in a "server" class, and the interface (the client) is in another project.
The server is as follows:
package webservice.server;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
#WebService
public class Calculator {
public static void main(String[] args) {
System.out.println("Server started at: http://localhost:12345/calc");
Endpoint.publish("http://localhost:12345/calc", new Calculator());
}
public int compute(int x, int y, String operation) {
return Calculator.calculate(x, y, operation);
}
public static int calculate(int x, int y, String operation) {
int result;
String op;
if ("ADD".equals(operation)) {
result = x + y;
op = "+";
} else if ("SUB".equals(operation)) {
result = x - y;
op = "-";
} else if ("MULT".equals(operation)) {
result = x * y;
op = "*";
} else if ("DIV".equals(operation)) {
result = x / y;
op = "/";
} else {
// defaults to SUB
result = x - y;
op = "-";
}
log(x, y, result, op);
return result;
}
private static void log(int x, int y, int result, String op) {
System.out.format("%d %s %d = %d%n", x, op, y, result);
}
}
With this server running, I run the following command in the Terminal if the IntelliJ IDEA IDE I'm using:
wsimport -keep -p webservice.client http://localhost:12345/calc?wsdl
, to create the client files, creating automatically the following structure (I'm using IntelliJ Community):
Currently, I am able to start my Calculator class (my server), and after I can start my CalculatorClient class to perform the calculations I need. Here is the code of this client:
package webservice.client;
public class CalculatorClient {
/**
* Starts the web service client.
*/
public static void main(String[] args) {
CalculatorService client = new CalculatorService();
Calculator calculatorService = client.getCalculatorPort();
int result = calculatorService.compute(10, 20, "ADD");
System.out.println("Returned value from server: " + result);
}
}
With the following result:
Returned value from server: 30
Process finished with exit code 0
As you can see, the Calculator client sends two values and the operation to the server via the webservice created, and the server returns the value to the client, so it can be printed.
This runs perfectly, so now my question is: How can I add this Calculator server class to an Apache Tomcat service? Is that possible? I've downloaded and installed the Apache Tomcat to my PC to learn how can I create webservices like this, just functionalities that will be accessed from another client program, as the CalculatorClient does, and these functionalities will be running on a local PC.
In my Apache Tomcat server I can see the following:
How can I add my Calculator class (the server) here and start it or stop it as needed, so my CalculatorClient can access to it? Is that possible? If not, how can I create services in Java like my Calculator class and add them to this Apache Tomcat server?
Thanks for any help or suggestion!
Daniel.
I need to reference a .Net dll in java. I have used jni4net libraries for the same. I have followed the steps mentioned in the video below :
https://www.youtube.com/watch?time_continue=351&v=8OoSK_RWUe4
I have followed all the steps required to reference jni4net libraries but i get the following runtime Exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: orionforpython.DynamicOrion.__ctorDynamicOrion0(Lnet/sf/jni4net/inj/IClrProxy;)V
at orionforpython.DynamicOrion.__ctorDynamicOrion0(Native Method)
at orionforpython.DynamicOrion.<init>(DynamicOrion.java:25)
at com.orion.OrionForJava.main(OrionForJava.java:16)
After following all the steps, This is my code:
package com.orion;
import net.sf.jni4net.Bridge;
import orionforpython.*;
import java.io.*;
class OrionForJava {
public static void main(String[] args) throws IOException {
Bridge.setVerbose(true);
Bridge.init();
File proxyAssemblyFile=new File("OrionForPython.dll");
Bridge.LoadAndRegisterAssemblyFrom(proxyAssemblyFile);
DynamicOrion orion=new DynamicOrion();
String res=orion.ReqLogin("user", "pwd", "");
System.out.print(res);
}}
I have tried executing the same using NetBeans 8.1 IDE but with no success. I am using jni4net-0.8.8.0 version and Eclipse IDE for Java Developers
Version: Oxygen.3 Release (4.7.3)
Any assistance would be helpful!
I used jni4net library to call c# dlls from java and it is working fine. I used a lightly different approach to initialize jni4net.
try {
Bridge.setVerbose(true);
Bridge.init(new File("Full path to jni4net.n.w64.v40-0.8.8.0.dll"));
// where dlls to load is jni4net.n.w64.v40-0.8.8.0.dll,jni4net.n-0.8.8.0.dll,MyOriginalNETDll.dll,MyOriginalNETDll.j4n.dll (after proxygen processing)
for (String str : dllsToLoad) {
File dll = new File(rutaDlls + str);
Bridge.LoadAndRegisterAssemblyFrom(dll);
}
} catch (IOException e) {
LOG.error("Error jniBrige.", e);
}
I needed to use full path c:... to the dll to make it work. I also had to take care about .net framework version used to create assembly (need to use 4.0 in my case and java version 8)
Hopes this helps
We use JCOBridge which can be used in .NET Core (>= 3.1), .NET 5/6 and .NET Framework (>= 4.6.1). Referencing the DLL you need to call you will have full access to it and you can use it in your projects.
Consider the following C# snippet class available in a generic TestBridge.dll:
using System;
namespace TestBridge
{
public class MyClass
{
/// <summary>The method <c>HelloWorld</c> return the "Hello World!!" string</summary>
public String HelloWorld()
{
return "Hello World from C#!!";
}
/// <summary>The method <c>Add</c> return the sum of two double</summary>
public double Add(double a, double b)
{
return a + b;
}
/// <summary>The method <c>Add</c> return the sin of a double</summary>
public double Sin(double a)
{
return Math.Sin(a);
}
}
}
The methods of the previous class can be invoked from the following java code snippet:
import java.io.IOException;
import org.mases.jcobridge.*;
public class CSharpClassUse {
public static void main(String[] args) {
try {
try {
try {
JCOBridge.Initialize();
} catch (JCException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
//declare and create JCOBridge instance
JCOBridge bridge;
bridge = JCOBridge.CreateNew();
// adds the path where external assemblies can be found
bridge.AddPath("Path where is TestBridge.dll assembly");
// add REFERENCES to the .dll file you want to invoke
bridge.AddReference("TestBridge.dll");
// INSTANTIATE the .NET Object: JCObject is a meta object
JCObject theNetClassInstance = (JCObject) bridge.NewObject("TestBridge.MyClass");
double a = 2;
double b = 3;
double c = Math.PI/2;
//Invoke the C# class methods
String hello = (String) theNetClassInstance.Invoke("HelloWorld");
double result = (double) theNetClassInstance.Invoke("Add", a, b);
double sin = (double) theNetClassInstance.Invoke("Sin", c);
System.out.println(String.format("%s %.0f + %.0f = %.0f and sin(%.8f) = %.8f", hello, a, b, result, c, sin));
} catch (JCException jce) {
jce.printStackTrace();
System.out.println("Exiting");
return;
}
}
}
The previous java code produces the following output:
Hello World from C#!! 2 + 3 = 5 and sin(3,14159265) = 1,00000000
The previous example shown how use a C# class available in a DLL. If you need to invoke/integrate .NET graphic, that in generic sense are C# DLL too, JCOBridge also manages GUI integration (WPF/WinForms/AWT/Swing): look at these Examples
Hope it was useful and clear.
I'm trying to create a Web Service with Axis2 and Tomcat 7. Everything is working great except I don't understand the following behavior:
I've created a Web Service with 2 operations, one sets an int local variable and the other one returns it, code looks like this:
package testServer;
public class service {
public int number;
public void setNumber(int i){ this.number = i; }
public int getNumber(){ return this.number; }
}
Client side looks like this:
package testserver;
import java.rmi.RemoteException;
import testserver.ServiceStub;
import testserver.ServiceStub.*;
public class CallService {
public CallService(){};
public void call() throws RemoteException{
ServiceStub s = new ServiceStub();
ServiceStub.SetNumber params = new ServiceStub.SetNumber();
params.setI(2);
s.setNumber(params);
ServiceStub.GetNumber n = new ServiceStub.GetNumber();
ServiceStub.GetNumberResponse r = s.getNumber(n);
System.out.println("number is: " + r.get_return());
}
}
Now, I'm expecting to get a "number is: 2" but instead I'm getting a "number is: 0". Can Anyone explain that to me please?
Because at each invocation, a different instance of the class is used.
In the client, you only have a ServiceStub instance. But the server is creating a new instance of Service (check CAPITALIZATION!!) for each request you make.
This is not as bad as you may think, think that the server does not really know where the requests are from.
To get the 2, you could make the variable static, just for testing. The "real" solution would be calling your server business logic methods (EJBs, POJOs) and have them store and retrieve the value.
I have created a simple java web service class like follows
public class Customer {
private String customerName;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
I did this using Eclipse Indigo enterprise edition & I used Axis2 as soap engine. Every thing fine.I created web service successfully & deployed it on Tomcat 7 server(wsdl also ok).
Now I want create a client program which can update the name variable. I created web service client using Eclipse & it generates CustomerCallbackHandler & CustomerStub java classes automatically. But I don't know how to develop a client using that classes to update variable. Please help me....
I implemented a client like this...
import java.rmi.RemoteException;
import com.spikes.ws.CustomerWSStub.SetName;
import com.spikes.ws.CustomerWSStub.GetNameResponse;;
public class TestClient {
public static void main(String[] args) throws RemoteException{
CustomerWSStub.SetName obj = new CustomerWSStub.SetName();
obj.setName("Kenth");
CustomerWSStub.GetNameResponse res = new CustomerWSStub.GetNameResponse();
System.out.println(res.get_return());
}
}
But when I'm running the code It gives "null" as result. What is wrong?? & how can I correct that ??? please help me.....
Please list your webservice method. You have listed, I'm assuming the class you pass up.
CustomerWSStub.SetName obj = new CustomerWSStub.SetName();
obj.setName("Kenth");
You need to call the web method on the class
CustomerWSStub.SetName obj = new CustomerWSStub.SetName();
obj.setName("Kenth");
CustomerWSStub stub = new CustomerWSStub();
CustomerWSStub.GetNameResponse res = stub.GetName(obj);
Please post your actual web service method and that will be helpful.
So i'm trying to get my Apache xmlrpc client/server implementation to play ball. Everything works fine except for one crucial issue:
my handler class (mapped through the properties file org.apache.xmlrpc.webserver.XmlRpcServlet.properties) reacts as it should but it's constructor is called at every method invocation. It would seem that the handler class is instantiated at each call which is bad because I have data stored in instance variables that I need to save between calls.
How do I save a reference to the instantiated handler so that I can access it's instance variables?
So, for anyone else who still wants to use XMLRPC here's how I fixed this issue:
http://xmlrpc.sourceforge.net/
far superior to apache xmlrpc, in my opinion.
This is standard behaviour of Apache XMLRPC 3.x. http://ws.apache.org/xmlrpc/handlerCreation.html:
By default, Apache XML-RPC creates a new object for processing each
request received at the server side.
However, you can emulate the behaviour of XMLRPC 2.x, where you registered handler objects instead of handler classes, using a RequestProcessorFactoryFactory. I have written a custom RequestProcessorFactoryFactory that you can use:
public class CustomHandler implements RequestProcessorFactoryFactory {
Map<Class<?>, RequestProcessorFactory> handlers =
Collections.synchronizedMap(
new HashMap<Class<?>, RequestProcessorFactory>());
#Override
public RequestProcessorFactory getRequestProcessorFactory(Class pClass)
throws XmlRpcException {
return handlers.get(pClass);
}
public void addHandler(final Object handler) {
handlers.put(handler.getClass(), new RequestProcessorFactory() {
#Override
public Object getRequestProcessor(XmlRpcRequest pRequest)
throws XmlRpcException {
return handler;
}
});
}
}
This can then be used with e.g. a XMLRPC WebServer like this
WebServer server = ...
PropertyHandlerMapping phm = new PropertyHandlerMapping();
server.getXmlRpcServer().setHandlerMapping(phm);
Custom sh = new CustomHandler();
phm.setRequestProcessorFactoryFactory(sh);
Object handler = ... /** The object you want to expose via XMLRPC */
sh.addHandler(handler);
phm.addHandler(serverName, handler.getClass());
Maybe something to do with javax.xml.rpc.session.maintain set to true?
I know this is a really old post but I managed to solve the problem with Apache's Java XML-RPC.
First, I thought this could be solved with singleton class in Java but it doesn't work and throws "illegal access exception".
These are what I have done:
public class XmlRpcServer {
private static JFrame frame = new JFrame();
private static JPanel pane = new JPanel();
public static XmlRpcServer singleton_inst = new XmlRpcServer();
public XmlRpcServer() {
// I kept the constructor empty.
}
public static void main(String[] args) throws XmlRpcException, IOException {
// In my case, I put the constructor code here.
// Then stuff for XML-RPC server
// Server Part
WebServer ws = new WebServer(8741);
PropertyHandlerMapping mapping = new PropertyHandlerMapping();
mapping.addHandler("SERVER", singleton_inst.getClass());
ws.getXmlRpcServer().setHandlerMapping(mapping);
ws.start();
////
}
// I called doTheJob() from python via XML-RPC
public String doTheJob(String s) throws XmlRpcException {
loop();
return s;
}
// It executed loop() forever
private static void loop() throws XmlRpcException {
// Actual work is here
}
But metaspace increases gradually:
I worked too much on this metaspace issue when looping forever in Java but I couldn't figure out a solution.