Contribution repository and building a suite

Hi all,

I’m hacking on a proof-of-concept ‘InspectorMonkey’ for using JMX to get information from a running jME app into the SDK. I have a suite of modules (a jar + a wrapper module for use in the application and an SDK plugin). I was wondering how to best put that into the contribution repository.

My question is if I should keep my suite structure or if I should commit them as separate modules so that the repository “build suite” will work? Keeping my suite structure will keep the modules together and they don’t make much sense separate but then I guess the hudson machine will not build and publish them?

1 Like

The latter, single plugins in the repo suite. If they have inter-dependancies they will automatically install together.

1 Like

Thanks, I’ll commit them as separate modules.

@jmaasing said:
Thanks, I'll commit them as separate modules.

Cool. This sounds interesting. Theres various options for this, my initial plan was to allow attaching AppStates to the SceneApplication and then register them through some external file but I'm interested to see what you whipped up :)

Edit: You actually need a suite when you create them so they work well in the repo suite so its good you have that suite anyway.
@normen said:
Cool. This sounds interesting. Theres various options for this, my initial plan was to allow attaching AppStates to the SceneApplication and then register them through some external file but I'm interested to see what you whipped up :)


It's not "done" but the basic plumbing is in place so I committed anyway, hope I don't break the build :)

The reason for building this was twofold. I wanted to do some NetBeans plugins to learn about that (for other projects also). The other reason was to evaluate if JMX would be a good plumbing for integrating the SDK and jME applications.

So to that end, here is a walktrough of how it works.

The "problem":
The jME Application (your game) has interesting statistics that we want to see in the SDK, it might for example be the current scene graph, you might want to plot the FPS in a graph, or as in this example, I wanted to draw the TerrainGrid heightmap as a grey scale image.
In JMX parlance the application is the JMX Server and the SDK is the JMX Client.

Server side:
There is a 'TerrainGridInspector' class that listens to TerrainGrid updates (the inspectors cache handling seems broken right now). What it does is essentially keeping track of the float[] that is the "current" height field the camera is over and give it out on request. This class is also a Management class, a JMX MBean. To be a MBean means that there are certain restrictions a class must live up to, in this simple case it must implement an interface named [class]MBean that must be in the same package.

There is a TerrainGridInspectorAppState that handles registration of the TerrainGridInspector in the JMX server. This makes it possible for any JMX client in the same JVM to call methods on the MBean.

To make the JMX server listen to remote calls, which is what we want, the application must be launched with the following JVM flags:

-Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl = false

jconsole.html

This will set up an RMI server and tie all the knots together, so remote (inter JVMs) JMX is over RMI with all that entails. It is possible to set up the RMI server in code but I couldn't be bothered :)

Client side:
The client (the SDK plugin) lives in the HeightFieldVisualizer project. It consists of a Netbeans top component that can draw a float[] as a grey scale image. Pretty simple stuff and the GUI is far from done. The interesting JMX parts can be found in the AppFinder class.

It uses the JMX APIs to connect to the remote JMX server using an arcane URL.
When it has connected to the server (i.e. the application) it creates a JDK proxy to the remote bean and it can continue to call methods on that object. In practice it gets an instance of TerrainGridInspector. The rest is just GUI handling.

Pros:
JMX/RMI is a tried and tested protocol. There are many generic JMX clients (jconsole) that can be used to attach to a JMX enabled jME-application to test and instrument it even when the SDK does not have a plugin for it. It has built in security for attaching to remote servers (headless jME-game server for instance). In other words, it is completely decoupled from the SDK implementation.

Cons:
Setting up the server side (i.e. the game application) for remote calls isn't all that easy and there are some pitfalls. This can be made simpler using the Attach API but that isn't public (although it is documented). Using RMI-proxies is both easy and hard. It is easy to write code but it is hard to see what method calls are actually going across the wire and might fail. A matter of taste if you like your network calls to be explicit or hidden under a simple method invocation.
Another thing is, I have not even started looking into instrumenting Android applications, I suspect that it will not be possible using JMX/RMI.

Further work:
It would be interesting to try out the Attach API to make launching instrumented applications transparent for the user.
Another thing is to look into creating conventions for the JMX-naming scheme. That will enable the SDK to dynamically find out if and what MBeans are registered in an application. Using a common JMEMBean-interface with for example methods for querying which plugin can be used to view some statistics would even make it possible to launch any jME-application as a stand alone app, have the SDK connect to it and even tell the user which plugins can visualize the application statistics. Anythings possible :)

I'll continue to fix this plugin when I need a break from game development but it won't be highest priority for me. The main goal of having something to look at for evaluating JMX is achieved I'd say.

cheers,
JM

edit: clarified that it was the inspectors cache handling that was iffy, not the TerrainGrid.
2 Likes

Wow, I see… I guess this would go hand in hand with a project template as well eh? This is why I am reluctant to do any “game templates” yet, because I don’t know how much they will have to be configured/adapted… But I guess starting some API for properties etc access would make sense, a small library for this kind of stuffs…



Edit: Also I am atm basically rewriting the scene wrapper nodes so that they automatically update from some base objects… maybe a chance to get “remote” node trees in as well… Maybe I’ll commit the beginnings of the new scene opening system sooner than planned so you can take part / look at whats cooking.

Don’t rush it, I wont have much time to look the coming week, damn needy kids seem to want dinner every day :slight_smile:



The nice thing about RMI is that in many cases there wouldn’t be any difference between local nodes and remote nodes. So given that the GUI retrieves nodes from a some factory interface. Something like



[java]interface NodeFactory { Node getRootNode(); }

[/java]



it would in theory be just another implementation of that interface (depending on what data the nodes transfer over the wire of course).



One possiblity for launching the applications might be to add some checkbox in the project properties dialog for enabling “remote instrumentation” in the “Run” tab. Which would tack on the needed -D flags when launching the application.

Question, do I need to do anything more to get the plugins included in the update center? I followed the wiki about jMonkeyEngine SDK Contributions Update Center but as far as I can tell the modules needs to be added to the build suite project.properties also?



I tried adding them locally and ran “ant nbms” but my modules fail with: “No dependent module com.jme3.gde.core.baselibs”. Anyone know what that means?

Yes the project then needs to be referenced in the suite as well, the suite supplies the needed libraries.

I added the modules to project.properties but they don’t show up at http://direct.jmonkeyengine.com/updates/contributions/

Maybe they fail the build, is there someplace to see the build log?

The build fails… Theres import issues… The build on the server doesn’t have the jme libraries, only the SDK ones…

http://www.hub.jmonkeyengine.org:8080/job/jmp-contributions/986/console



I’ll see if I can add them on the server so that the referenced “jme3” library can be found… Else you can just commit the libraries by setting a library folder in the project settings (preferably “./lib”).

Hm… I can’t because its a build file you call directly yourself… However you should be able to reference it like this in your project properties:



libs.jme3.classpath=…/…/jME3-SDK-3.0RC2-nightly/workspace/engine/dist/lib/jME3-core.jar:…/…/jME3-SDK-3.0RC2-nightly/workspace/engine/dist/lib/jME3-networking.jar:…etc.



As it is available in your SDK already it should not be overwritten (in ANT properties are immutable) and on the server it should be set cause its not there.

Great! Thanks. Yes I could fix up the libraries in the module (using a lib) but wouldn’t it be better to have them referenced by symbolic name so that the contributions build against the “current” version of jme?

@jmaasing said:
Great! Thanks. Yes I could fix up the libraries in the module (using a lib) but wouldn't it be better to have them referenced by symbolic name so that the contributions build against the "current" version of jme?

The link I posted would be the "current" version that has been built just before.
@normen said:
The link I posted would be the "current" version that has been built just before.


Yeah, I didn't see your reply, sorry, I must remember to refresh the browser before posting :) I've set it up like you say. Wouldn't it be good to set those properties in the suite build file? I imagine that with that setup all contribution modules would compile the same locally and on Hudson without any customization in the project.properties.

I have an AppState in that JAR-file, then a wrapper module for it. I want to build the JAR file and then the wrapper and I didn't see a better way to get the JAR file built by the suite than to call the build myself.
@jmaasing said:
Yeah, I didn't see your reply, sorry, I must remember to refresh the browser before posting :) I've set it up like you say. Wouldn't it be good to set those properties in the suite build file?

Thats what I meant, as you call the build file yourself you are not in the main build file environment, I don't think adding it to the suite would work..?

I was thinking the wrapper module being part of the suite would pass on the properties needed to find the libraries to the JAR-project (the Ant task Ant can do that). That is obviously not the case, especially since Netbeans FAQ suggest to shut off property inheritance, doh :slight_smile:

http://wiki.netbeans.org/DevFaqWrapperModules



The latest build has the clever fix normen suggested but it didn’t work either, don’t know why. Anyways, thanks for your time.

Hm, okay, I will dig into this when I got time… Brute force workaround would be storing the jme jars in a lib folder and committing them as said…

@normen said:
Hm, okay, I will dig into this when I got time.. Brute force workaround would be storing the jme jars in a lib folder and committing them as said..

Actually I think your fix worked, but that inheritAll="false" I got from the NBs FAQ prevented some other good things from happening so the build failed. The latest build of the wrapper worked.
Next build will be without your fix (but inheritAll=true) since I think that should work. In either case I'll describe what worked on the wiki for wrapper modules since this seems to be a good way of having a JAR built and wrapped.
Thanks again.

Uh-oh… Better than inheritall would be to just copy over the needed properies to the new project I guess…