I have a gwt-application and want to connect to it's xmlrpc backend via a standalone xmlrpc-client (written e.g. with Apaches' xmlrpc-library).
Assume the project creates a servlet called TestServlet connected to the URL /test/test providing a Method public int add(int a, int b).
Calling the deployed servlet (running in a jetty on port 8080) with the code shown below, I get this error message in jettys' log:
javax.servlet.ServletException: Content-Type was 'text/xml'. Expected 'text/x-gwt-rpc'.
Is there any easy way to connect such a standalone xmlrpc-client with the gwt-enhanced xmlrpc-server?
I read about xmlrpc-gwt - but I want to keept the gwt dependencies for that standalone client minimal.
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:8080/test/test"));
config.setConnectionTimeout(60 * 1000);
config.setReplyTimeout(60 * 1000);
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
Object[] params = new Object[] {new Integer(2), new Integer(3)});
Integer result = (Integer) client.execute("TestServlet.add", params);
System.out.println(result);
GWT's RPC protocol is not related to XML/RPC . It's loosely based on JSON but it is not considered public, so you should not rely on its current form for interoperability.
Related
I have Spring Boot Camel application where rest apis are exposed using camel-restlet
Sample route
#Component
public class AppRoute extends RouteBuilder{
public void configure(CamelContext context){
from("restlet:employee?restletMethods=GET").log("${body}");
}
}
The App runs perfect ( spring-boot:run ). but am unable to locate under which path the API is exposed. Log has no information.
Every API i hit returns 404. Log shows the route has been started. Under which path is it running. And how do I change it?
Note: Please dont suggest any XML based configuration. Anything that I can put under #Configuration would be perfect
I would go with the Rest DSL which is supported by the camel-restlet component like this
restConfiguration().component("restlet").port(8080);
rest("/rest")
.get("employee")
.route().log("${body}")
.endRest();
And this route will listen to the following url
http://localhost:8080/rest/employee
EDIT:
I guess you could do something like without using the Rest DSL
String host = InetAddress.getLocalHost().getHostName();
from("restlet:http://" + host + contextPath + "/employee?restletMethods=GET").log("${body}")
The port and context path are configurable with the following properties
camel.component.restlet.port=8686
server.servlet.context-path=/my-path
The context path can be injected in the routeBuilder with
#Value("${server.servlet.context-path}")
private String contextPath;
According to the documentation, the format of the URI in a restlet endpoint definition should be the following:
restlet:restletUrl[?options]
Where restletUrl should have the following format:
protocol://hostname[:port][/resourcePattern]
So in your case you could define the URI in the following way:
from("restlet:http://localhost/employee?restletMethods=GET")
This should make the endpoint available under the following URL:
http://localhost/employee
Which you can test e.g. in a web browser.
Use the first of the three configuration methods described here:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/ext/org/restlet/ext/servlet/ServerServlet.html
You should be able to customize it using the Component:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/api/org/restlet/Component.html?is-external=true
See in particular setServers() methods (or XML equivalent) to change the hostname and port.
I am trying Ribbon configuration with RestTemplate based on bookmark service example but without luck, here is my code:
#SpringBootApplication
#RestController
#RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)
public class BookmarkServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BookmarkServiceApplication.class, args);
}
#Autowired
RestTemplate restTemplate;
#RequestMapping("/hello")
public String hello() {
String greeting = this.restTemplate.getForObject("http://foo/hello", String.class);
return String.format("%s, %s!", greeting);
}
}
with error page as below:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Mar 22 19:59:33 GMT+08:00 2016
There was an unexpected error (type=Internal Server Error, status=500).
No instances available for foo
but if I remove annotation #RibbonClient, everything will be just ok,
#RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)
and here is SampleRibbonConfiguration implementation:
public class SampleRibbonConfiguration {
#Autowired
IClientConfig ribbonClientConfig;
#Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
#Bean
public IRule ribbonRule(IClientConfig config) {
return new AvailabilityFilteringRule();
}
}
Is it because RibbonClient can not work with RestTemplate together?
and another question is that does Ribbon configuration like load balancing rule could be configured via application.yml configuration file?
as from Ribbon wiki, seems we can configure Ribbon parameters like NFLoadBalancerClassName, NFLoadBalancerRuleClassName etc in property file, does Spring Cloud also supports this?
I'm going to assume you're using Eureka for Service Discovery.
Your particular error:
No instances available for foo
can happen for a couple of reasons
1.) All services are down
All of the instances of your foo service could legitimately be DOWN.
Solution: Try visiting your Eureka Dashboard and ensure all the services are actually UP.
If you're running locally, the Eureka Dashboard is at http://localhost:8761/
2.) Waiting for heartbeats
When you very first register a service via Eureka, there's a period of time where the service is UP but not available. From the documentation
A service is not available for discovery by clients until the
instance, the server and the client all have the same metadata in
their local cache (so it could take 3 heartbeats)
Solution: Wait a good 30 seconds after starting your foo service before you try calling it via your client.
In your particular case I'm going to guess #2 is likely what's happening to you. You're probably starting the service and trying to call it immediately from the client.
When it doesn't work, you stop the client, make some changes and restart. By that time though, all of the heartbeats have completed and your service is now available.
For your second question. Look at the "Customizing the Ribbon Client using properties" section in the reference documentation. (link)
I am new to java RMI, actually I wrote, compiled and started rmic, and also tried to start server but failed due to _stub 'ClassNotFound' exception..... I'm using java 7... I searched a lot on Google but nobody told step by step example that could work...I got some idea about stteing codebase and security policy but not very clear suggestion that how to do it.. please help telling me steps including command-line .......... please... I have everything just tell me how to start server, and required settings like codebase or policy settings etc... Thanks
You don't need to use rmic. Instead, create your server object and call one of the exportObject() method overloads that has the port parameter. For example,
MyRemoteIntf stub = UnicastRemoteObject.exportObject(server, 0);
This will cause RMI to generate the stub automatically. (The documentation is horribly unclear on this point. If you use the version without the port parameter, it will use only the old, rmic-generated stubs instead of generating them automatically.)
Also, make sure that your remote interface is in the codebase of both the registry and any clients. You'll get different errors if you haven't done this properly. This has been answered a bunch of times on Stackoverflow already; search for "rmi ClassNotFoundException".
There is no need to use the rmic command since java (J2SE) 5.0 the stubs are dynamically generated at runtime.
Here is a basic step by step example of how to use RMI.
First define the Remote interface that defines what the client can see and do:
public interface FooService extends Remote {
// Don't forget to add throws RemoteException.
public void bar() throws RemoteException;
}
NOTE: if you do not add throws RemoteException to the method declaration you will encounter the following exception:
java.lang.IllegalArgumentException: illegal remote method encountered: public abstract void RMIExample.FooService.bar()
After you defined what the client can do you must define the concrete implementation of the methods on the server slide:
public class FooServiceImpl extends UnicastRemoteObject implements FooService {
public FooServiceImpl() throws RemoteException {
super();
}
public void bar() {
System.out.println("I was remotely invoked!");
}
}
The implementation class must inherit from UnicastRemoteObject and implement the Remote interface you defined earlier and the class must have a constructor that throws RemoteException.
Now that you have fully defined the remote functionality you must bind the implementation object to a URL on the server side:
// 4000 is the port to listen on.
LocateRegistry.createRegistry(4000);
Naming.rebind("//127.0.0.1:4000/foobar", new FooServiceImpl());
Now that you have your server up and running you need a stub instance A.K.A a proxy in the client side:
FooService fooService =
(FooService)Naming.lookup("//127.0.0.1:4000/foobar");
and finally invoke the remote method:
fooService.bar();
the following should be printed on the server side:
I was remotely invoked!
References:
http://en.wikipedia.org/wiki/Java_remote_method_invocation
http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/relnotes.html
I have service in which i am accessing few configuration properties from grailsApplication
I am injecting it like this
class MyWebService{
def grailsApplication
WebService webService = new WebService()
def getProxy(url, flag){
return webService.getClient(url)
}
def getResponse(){
def proxy = getProxy(grailsApplication.config.grails.wsdlURL, true)
def response = proxy.getItem(ItemType)
return response
}
}
When i call getProxy() method, i see this in tomcat logs
No signature of method: org.example.MyWebService.getProxy() is applicable for argument types: (groovy.util.ConfigObject, java.lang.Boolean) values: [[:], true]
Possible solutions: getProxy(), getProxy(java.lang.String, boolean), setProxy(java.lang.Object)
which means grailsApplication is not getting injected into the service, is there any alternate way to access configuration object ? according to burtbeckwith's post configurationholder has been deprecated, can't think of anything else.
Interestingly the very same service works fine in my local IDE(GGTS 3.1.0), that means locally grailsApplication is getting injected, but when i create a war to deploy to a standalone tomcat, it stops getting injected.
I seem to have figured out the problem, actually grailsApplication is getting injected properly otherwise it would have thrown a null pointer exception, i feel the configuration properties are not getting added. Actually the scenario is like, i have a separate custom configuration file which holds configuration data for different environments, my application listens to the environement type(a variable which is set from tomcat) and based on that merges the corresponding config properties from my custom configuration file. i think those propreties are probably not getting added
I am trying to write a GWT back-end using the RPC model for java servlets.
Is it possible to ssh tunnel within an RPC in order to communicate with a remote sql database?
The code I try to execute is below, using Jsch. The error occurs on "session.connect();"
String host="xxxxx.xxx.edu";
String user="username";
String password="password";
Session session= null;
try{
//Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
}
The runtime error I get on the 'session.connect()' line is as follows: (scroll right to see whole error)
com.jcraft.jsch.JSchException: java.security.AccessControlException: access denied (java.net.SocketPermission xxxxx.xxx.edu resolve)
at com.jcraft.jsch.Util.createSocket(Util.java:341)
at com.jcraft.jsch.Session.connect(Session.java:194)
at com.jcraft.jsch.Session.connect(Session.java:162)
at com.front.server.GameServiceImpl.createGame(GameServiceImpl.java:39)
The frustrating part about this is that I copied/pasted the exact same code into a simple java program and it works. So I know the code is correct; obviously the jetty server which GWT creates for local testing has a problem executing the code. What else can I do / what should I be doing in this situation with GWT? Shouldn't the back-end of a GWT application have the capacity to ssh??
I suggest you try running your gwt app with a different web container (Tomcat, JBoss). You can still make use of debugging functionality by running the hosted mode with the -noserver flag.
See here