JavalibCore/dynamic library API usage in a remote Java test library

244 views
Skip to first unread message

Kevin O.

unread,
Apr 11, 2012, 11:33:28 PM4/11/12
to robotframework-users
I really like the JavalibCore stuff. I would like to use it in a
remote library.
jrobotremoteserver seems to be stalled in its infancy, so I decided to
try something else.
I took robotremoteserver.py and modified it to take advantage of
Jython so it can talk to my Java class that subclasses
AnnotationLibrary (a dynamic library API implementation).
getKeywordNames, getKeywordDocumentation, and getKeywordArguments are
all working. runKeyword is partially working.

The problem is how slow the thing is. RIDE/Robot take a few seconds
to fetch the doc & args PER keyword.

Should I give up and look to contributing to jrobotremoteserver?
What is anyone else doing who can't stand using the static library
API?

Thanks,
Kevin

David

unread,
Apr 12, 2012, 2:47:41 AM4/12/12
to robotframework-users
Interesting thread.

As the developer of jrobotremoteserver, I would appreciate any
contributions to improving it (or even forks). I haven't had much time
to resume enhancement work on it, nor am I up to speed on the
JavaLibCore architecture to plug/integrate it with the server.

One question/thought though, isn't the remote library interface by
design using the dynamic library API? At least in interfacing to Robot
it is dynamic. Perhaps you meant internally within the library? Or
that you just want to use JavaLibCore's approach remotely?

If you just want to separate out your library into multiple classes,
you could just use a master wrapper class that can call all the other
classes and use reflection upon the wrapper class. Or figure something
similar on how to load multiple classes into the server to serve.

It would also be interesting to see JavaLibCore's design be available
to other platforms for use with Robot, like say .NET/C#, etc.

What in particular is slow with your approach? Can you elaborate? Is
it slow every time a keyword executed or only on first execute of each
specific keyword (cached thereafter by the JVM)? Are you saying it's
slow from both RIDE and robot alone or just from RIDE?

Is it just slow fetching the doc and arguments, or also slow to return
list of keywords (names) from the library? How about executing
keywords (which you say partially works), slow also?

Another test you can do is make XML-RPC keyword call to your server to
see how long it takes to get response back. This will help you narrow
down whether issue is at Robot framework side or at the remote library
side.

Kevin O.

unread,
Apr 12, 2012, 12:19:26 PM4/12/12
to robotframe...@googlegroups.com
The horrible slowness was not the remote library at all.
I was using localhost as the host name in my usage of Remote, which on my machine was taking several seconds for RF(pybot) or RIDE to resolve.  See [1] for a very similar issue with HTTPServer instead of SimpleXMLRPCServer.

I found two solutions:
1. Use the loopback address in the URL argument for Remote, e.g. http://127.0.0.1:8270/
2. In the hosts file, override the default resolution by uncommenting this line:
# 127.0.0.1       localhost
 This forces localhost to resolve to the IPv4 loopback address (127.0.0.1) instead of the IPv6 one (::1).

After the fix it is really fast.

> One question/thought though, isn't the remote library interface by design using the dynamic library API?
Yes, I was referring to the internal/user class being dynamic.

Now that I see the developer of jrobotremoteserver is around, I won't be afraid to throw a commit out there.

The annotation-based way to supply keyword arguments and documentation that AnnotationLibrary uses (@RobotKeyword & @ArgumentNames) are the de facto standard for runtime access to that information.

Shouldn't be to hard to support JavalibCore.  Need to choose between different invoication handlers.

If the user class implements org.robotframework.javalib.library.RobotJavaLibrary, use one of two wrapper classes instead of RemoteServerMethods:
* full API (AnnotationLibrary only) if it also implements org.robotframework.javalib.library.KeywordDocumentationRepository.  This means get_keyword_arguments and get_keyword_documentation will be exposed.
* minimal API (just get_keywords & run_keyword) otherwise
Otherwise use the RemoteServerMethods class

The wrappers are necessary because the JavalibCore classes use camel case (e.g. getKeywords) and need to be mapped to the pythonicly named methods (e.g. get_keywords) before being exposed via the RPC server.

Pekka Klärck

unread,
Apr 12, 2012, 5:11:10 PM4/12/12
to korm...@gmail.com, robotframework-users
2012/4/12 Kevin O. <korm...@gmail.com>:

> I really like the JavalibCore stuff.  I would like to use it in a
> remote library.
> I took robotremoteserver.py and modified it to take advantage of
> Jython so it can talk to my Java class that subclasses
> AnnotationLibrary (a dynamic library API implementation).
> getKeywordNames, getKeywordDocumentation, and getKeywordArguments are
> all working.  runKeyword is partially working.

It's a known limitation of the Python version of the remote server
(robotremoteserver.py) that it doesn't support dynamic libraries [1].
Because this is the reference implementation, I assume that other
remote servers don't support the dynamic library API either.

[1] http://code.google.com/p/robotframework/issues/detail?id=187

Adding the support for dynamic libraries into robotremoteserver.py
would be great and should be too hard either. Since you have already
started to work on this, are you interested in collaborating? If yes,
I think it would be easiest to move robotremoteserver.py into its own
project in GitHub so that collaboration would be easier. That way we
could also make the tool easy to install and new version of the tool
wouldn't be dependent on Robot Framework releases.

Cheers,
.peke
--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org

David

unread,
Apr 12, 2012, 9:53:39 PM4/12/12
to robotframework-users
Thanks for the input Kevin. I'll look into the mentioned JavaLibCore
classes when I have time.

Unless using JavaLibCore (minimal API) behaves same as current
RemoteServerMethods in how simple Java libraries are reflected/exposed
(so library developers don't need to change their library interface),
to provide alternate options and backwards compatibility for
jrobotremoteserver, probably ideal to offer a command line parameter/
switch on startup whether to load a library using JavaLibCore or
RemoteServerMethods. And for JavaLibCore case, best to aim for full
API rather than minimal, though could start implementing the minimal
API first.

Also, if you want to make/offer commits but feel the Google code site
for the project is inefficient for collaboration, I can move it over
to GitHub as well, like Pekka suggests for the Python server. I just
started with Google code as it was easier for me to work with at the
time.

On Apr 12, 9:19 am, "Kevin O." <kormb...@gmail.com> wrote:
> The horrible slowness was not the remote library at all.
> I was using localhost as the host name in my usage of Remote, which on my
> machine was taking several seconds for RF(pybot) or RIDE to resolve.  See
> [1] for a very similar issue with HTTPServer instead of SimpleXMLRPCServer.
>
> I found two solutions:
> 1. Use the loopback address in the URL argument for Remote, e.g.http://127.0.0.1:8270/
> [1]http://stackoverflow.com/questions/2617615/slow-python-http-server-on...

Kevin O.

unread,
Apr 13, 2012, 10:09:26 AM4/13/12
to robotframe...@googlegroups.com
I think enhancing robotremoteserver.py to work with dynamic libraries is the first thing to do.  If done in a way that works with Jython, then both Python test library authors as well as Java ones will benefit.

I did try and start working with jrobotremoteserver though.

I started off trying to Mavenize your project.  I couldn't because the version of Redstone that is in the JBoss repo does not have the default handler patch you mentioned, even though it is version 1.1.1.  By the way, the redstone that is embedded in jrobotremoteserver-1.0.jar is patched, but the xmlrpc-1.1.1.jar that is in the jrobotremoteserver-1.0r1.zip with jrobotremoteserver-1.0.jar is not.  The 1.1.1 on SF is patched.
Seriously confusing when a project releases a patched version without touching the version name/number.

The way forward would be to switch to apache-xmlrpc and that will take more effort.  I will work on robotremoteserver.py and go from there.

Not using Maven is why I think you had trouble compiling when using the apache-xmlrpc server.  I don't know why they don't nudge people into using Maven on the download/release pages of their projects.  Maven is, after all an Apache project.

I did code a reliable way of detecting a dynamic library that is independent of the JavalibCore interfaces.  I made a factory that can detect the type of user library and return the appropriate handler to register with the xmlrpc server, whether it be RemoteServerMethods or one of the wrappers for dynamic libraries.  No need for command line options if done this way.

JavaLibCore does not behave the same as RemoteServerMethods does.  Besides the Java instead of Python naming convention, the return type for runKeyword is Object.  The dynamic library wrappers can easily take the return object and put it in a Map just like RemoteServerMethods does.  The wrappers should implement the implied interface that RemoteServerMethods does.

As for capturing stdout, you can redirect stdout using System.setOut.  Did you try that?

If you want what I have done so far let me know.

Pekka Klärck

unread,
Apr 16, 2012, 8:40:39 AM4/16/12
to korm...@gmail.com, robotframe...@googlegroups.com
2012/4/13 Kevin O. <korm...@gmail.com>:

> I think enhancing robotremoteserver.py to work with dynamic libraries is the
> first thing to do.  If done in a way that works with Jython, then both
> Python test library authors as well as Java ones will benefit.

As I wrote earlier, I agree that this is a good idea. I discussed with
other core developers and we agreed that moving the Python remove
server into a separate project is a good idea and we'll probably to
that this week. If adding the support for dynamic libs is as easy as I
assume it is, we probably will do that at the same time.

Pekka Klärck

unread,
Apr 16, 2012, 8:55:34 AM4/16/12
to mang...@gmail.com, robotframework-users
2012/4/13 David <mang...@gmail.com>:

> Also, if you want to make/offer commits but feel the Google code site
> for the project is inefficient for collaboration, I can move it over
> to GitHub as well, like Pekka suggests for the Python server. I just
> started with Google code as it was easier for me to work with at the
> time.

Notice that for us starting a separate project for the Python remote
server is more important than where it is hosted. Now the server code
is under Robot Framework main project and thus somewhat tied to its
release schedule. More importantly, having a separate project makes it
possible (or at least a lot easier) to make the remote server easy to
install. My hope is that soon you can run something like `pip install
robotframework-remoteserver` to get the server installed.

The above said, I do believe GitHub offers better tools for
collaborative development than Google Code. Easy forking and pull
requests is a brilliant concept. The benefits aren't that big that
moving existing projects over always makes sense, though. There are
also other good open source hosting services (e.g.
https://bitbucket.org) that you may want to consider, especially if
you don't particularly like Git.

Kevin O.

unread,
Apr 29, 2012, 11:49:14 PM4/29/12
to robotframe...@googlegroups.com
Just so you know I am still here and working on it.
I created a Java example lib with 83 kws and passing all 81 acceptance tests.  The build is Maven using JavaLibCore and integrated into run.py.  I am not attempting to support static Java libraries as that would be a lot more work.
I parameterized the Python and Java example libs to start as static, minimal dynamic and full dynamic and modified run.py to take advantage of that.
There is still some work to do.
I also added retrieving kw doc from static Python libraries as that seems important.
Should be ready to send a diff soon, regardless of where Robot Remote Server calls home.

Pekka Klärck

unread,
May 1, 2012, 4:25:04 PM5/1/12
to korm...@gmail.com, robotframe...@googlegroups.com
2012/4/30 Kevin O. <korm...@gmail.com>:
Is all this work related to the Python remote server? Sounds awesome!

We have moved the server GitHub [1] but the work setting up the
project there is still in progress. Actual code, tests and the test
infrastructure ought to be fine now, but all the documentation still
refers to the old situation when the server was hosted under Robot
Framework project along with a Ruby server. That Ruby server has, by
the way, bee living a better life as a separate project for some time
already [2].

The best way forward would probably be you forking the project on
GitHub and developing your enhancements there. That way we can easily
see the changes you have been doing and you can send pull requests to
the official project. Since you have been working with multiple
separate tasks, it would probably help if you could separate the work
into different branches. I'm personally somewhat new with Git and
GitHub, but I'm sure we'll manage this somehow.

[1] https://github.com/robotframework/PythonRemoteServer
[2] https://github.com/semperos/robot-remote-server-rb
Reply all
Reply to author
Forward
0 new messages