I am an old hand at cl, but java is still a bit of a mystery to me. I am particularly puzzled as to why, when trying to use the apache http components library to do a simple http get in abcl, I cannot make it work. My code:
(defun http-get (url) (let* ((url (jnew (jclass "java.lang.String") url)) (client-class (jclass "org.apache.http.impl.client.DefaultHttpClient")) (client-obj (jnew client-class)) (get-class (jclass "org.apache.http.client.methods.HttpGet")) (get-obj (jnew get-class url))) (jcall (jmethod client-class "execute") client-obj get-obj)))
And the java code from the apache tutorial http://hc.apache.org/httpcomponents-client-4.0.3/tutorial/html/fundamentals....:
HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("http://localhost/"); HttpResponse response = httpclient.execute(httpget); ...
For some reason, my code fails with No such method: org.apache.http.impl.client.DefaultHttpClient.execute().
I do have the appropriate jars in my class path.
The java code specifically calls the execute method on its instantiated httpclient, but I cannot do the same from abcl. This method is inherited from org.apache.http.impl.client.AbstractHttpClient, in case that makes a difference. (http://hc.apache.org/httpcomponents-client-4.0.3/httpclient/apidocs/index.ht...).
Thanks for any insight!
-Kevin
I don't have httpcomponents, so this is not tested ...
But your problem is probably that (jmethod client-class "execute") is looking for a zero argument execute method, and the class does not have one. Based on the api docs (and your attempted method call), I think you want
(jmethod client-class "execute" "org.apache.http.client.methods.HttpUriRequest")
-david k.
On Tue, Oct 12, 2010 at 1:01 PM, Kevin Raison raison@chatsubo.net wrote:
I am an old hand at cl, but java is still a bit of a mystery to me. I am particularly puzzled as to why, when trying to use the apache http components library to do a simple http get in abcl, I cannot make it work. My code:
(defun http-get (url) (let* ((url (jnew (jclass "java.lang.String") url)) (client-class (jclass "org.apache.http.impl.client.DefaultHttpClient")) (client-obj (jnew client-class)) (get-class (jclass "org.apache.http.client.methods.HttpGet")) (get-obj (jnew get-class url))) (jcall (jmethod client-class "execute") client-obj get-obj)))
And the java code from the apache tutorial http://hc.apache.org/httpcomponents-client-4.0.3/tutorial/html/fundamentals....:
HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("http://localhost/"); HttpResponse response = httpclient.execute(httpget); ...
For some reason, my code fails with No such method: org.apache.http.impl.client.DefaultHttpClient.execute().
I do have the appropriate jars in my class path.
The java code specifically calls the execute method on its instantiated httpclient, but I cannot do the same from abcl. This method is inherited from org.apache.http.impl.client.AbstractHttpClient, in case that makes a difference. (http://hc.apache.org/httpcomponents-client-4.0.3/httpclient/apidocs/index.ht...).
Thanks for any insight!
-Kevin
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Tue, Oct 12, 2010 at 10:18 PM, David Kirkman dkirkman@ucsd.edu wrote:
I don't have httpcomponents, so this is not tested ...
But your problem is probably that (jmethod client-class "execute") is looking for a zero argument execute method, and the class does not have one. Based on the api docs (and your attempted method call), I think you want
(jmethod client-class "execute" "org.apache.http.client.methods.HttpUriRequest")
Or if you don't mind paying a certain runtime penalty on each invocation, you can use the shorter (jcall "execute" client-obj get-obj) and let ABCL figure out the exact method to call. Also you can use url directly if it's a Lisp string because ABCL will convert it to a Java string automatically when you pass it to a Java method.
hth, Alessio
Thanks for the pointers, David and Alessio. I was able to implement my HTTP client in abcl with the knowledge that you provided. As I move on to the next phase of my project, I have run into another issue that I can't figure out how to solve without coding in java (which I would prefer not to do, if I can help it).
The issue is this: I am trying to build on Apache CXF library, using just its simple interface for defining a soap service. The java pattern is like this:
public interface HelloWorld { String sayHi(String text); }
public class HelloWorldImpl implements HelloWorld { public String sayHi(String text) { return "Hello " + text; } }
import org.apache.cxf.frontend.ServerFactoryBean;
HelloWorldImpl helloWorldImpl = new HelloWorldImpl(); ServerFactoryBean svrFactory = new ServerFactoryBean(); svrFactory.setServiceClass(HelloWorld.class); svrFactory.setAddress("http://localhost:9000/Hello"); svrFactory.setServiceBean(helloWorldImpl); svrFactory.create();
I would like to be able to all of this directly in abcl, meaning code the interface, implementation and serverFactory without using java. I don't see a way to do this with abcl. Several things are unclear to me:
1. I can't find a way to specify an interface in abcl; if such a thing is not possible, all is maybe not lost. Could I do the interface spec in java and the implementation in abcl? 2. CLOS classes don't seem to correspond to java classes, so assuming issue #1 is solved, how would I specify an implementation of the interface in abcl? 3. As for the serverFactory: if #1 and #2 are solved, the only piece of this that isn't clear to me is how to translate
svrFactory.setServiceClass(HelloWorld.class);
to abcl.
Thanks again for the assistance; if my questions are too junior for this list, please don't hesitate to point me somewhere else.
Cheers. Kevin
On 10/12/2010 02:19 PM, Alessio Stalla wrote:
On Tue, Oct 12, 2010 at 10:18 PM, David Kirkmandkirkman@ucsd.edu wrote:
I don't have httpcomponents, so this is not tested ...
But your problem is probably that (jmethod client-class "execute") is looking for a zero argument execute method, and the class does not have one. Based on the api docs (and your attempted method call), I think you want
(jmethod client-class "execute" "org.apache.http.client.methods.HttpUriRequest")
Or if you don't mind paying a certain runtime penalty on each invocation, you can use the shorter (jcall "execute" client-obj get-obj) and let ABCL figure out the exact method to call. Also you can use url directly if it's a Lisp string because ABCL will convert it to a Java string automatically when you pass it to a Java method.
hth, Alessio
On Thu, Oct 14, 2010 at 8:15 PM, Kevin Raison raison@chatsubo.net wrote:
Thanks for the pointers, David and Alessio. I was able to implement my HTTP client in abcl with the knowledge that you provided. As I move on to the next phase of my project, I have run into another issue that I can't figure out how to solve without coding in java (which I would prefer not to do, if I can help it).
The issue is this: I am trying to build on Apache CXF library, using just its simple interface for defining a soap service. The java pattern is like this:
public interface HelloWorld { String sayHi(String text); }
public class HelloWorldImpl implements HelloWorld { public String sayHi(String text) { return "Hello " + text; } }
import org.apache.cxf.frontend.ServerFactoryBean;
HelloWorldImpl helloWorldImpl = new HelloWorldImpl(); ServerFactoryBean svrFactory = new ServerFactoryBean(); svrFactory.setServiceClass(HelloWorld.class); svrFactory.setAddress("http://localhost:9000/Hello"); svrFactory.setServiceBean(helloWorldImpl); svrFactory.create();
I would like to be able to all of this directly in abcl, meaning code the interface, implementation and serverFactory without using java. I don't see a way to do this with abcl. Several things are unclear to me:
- I can't find a way to specify an interface in abcl; if such a thing
is not possible, all is maybe not lost. Could I do the interface spec in java and the implementation in abcl?
There's currently no way to define a Java interface in ABCL. However, there's a way to implement one (which is not equivalent to the Java way of doing it - it's slower, because it uses reflection). Look at jmake-proxy in java.lisp.
- CLOS classes don't seem to correspond to java classes, so assuming
issue #1 is solved, how would I specify an implementation of the interface in abcl?
There are several ways: a single function manually dispatching on the method name, a Lisp package with a symbol for each method in the interface, a hash map of method name -> closure entries.
- As for the serverFactory: if #1 and #2 are solved, the only piece of
this that isn't clear to me is how to translate
svrFactory.setServiceClass(HelloWorld.class);
to abcl.
(jcall "setServiceClass" svr-factory (jclass "com.whatever.HelloWorld"))
or
(jcall (jmethod "org.apache.cxf.frontend.ServerFactoryBean" "setServiceClass" "java.lang.Class") svr-factory (jclass "com.whatever.HelloWorld"))
Regards, Alessio
armedbear-devel@common-lisp.net