View Full Version : Java version of the plugin API?
Ron
October 13th, 2002, 12:55 PM
Any help is very welcome! Sadly I have no experience with Java and C interfacing. Maybe there is someone out there that can help.
Ron
October 13th, 2002, 12:55 PM
Actually listeners have been implemented in the gvms/gvms-lua. Its all a matter of the API exporting them. They work pretty simple, though I'm not sure how to go about this in java. To register as a listener one calls a function with a target handle, and the gvms will send a signal if something changes.
On the GUI end, at this point the GUI and the core are completely separate, the only thing that they share is the command tree and the settings structure. Everything else is handled through window/thread messages. So in theory I am able to compile an executable without a GUI, or extend it to load a GUI from a DLL. Actually this is planned for 4.0. Sadly its the same old song,.. time, more precisely the shortage thereof.
Ron
October 13th, 2002, 12:55 PM
I've added it to the todo list. I've been saving up some API changes so I don't have to update the API all the time.
Mark F
October 13th, 2002, 12:55 PM
For generating events, probably it doesn't matter which Java plugin it came from once it gets over to Girder. They all look to come from the one device number.
and
Inside Girder, the command needs to identify which Java plugin it belongs to. Perhaps steal one of the string members for this.
The send_event() interface requires the inclusion of the DeviceID. On the surface, this appears to allow a single Girder plugin to send events from multiple Java plugins with each Java plugin having a unique ID.
If this actually works, would it make things "easier"? :D
Mark F
October 13th, 2002, 12:55 PM
Girder 3.2.X is not designed to have it's GUI replaced. As such, concepts like listeners are not available.
As for whether adding new function to the Girder core is "simple" or can be done in a "backwards compatible" manner, I'll leave those questions to Ron as he is the only one able to update the code.
MMcM
October 13th, 2002, 12:55 PM
I know more about JNI that one should probably be prepared to admit. :wink: I don't have an abundance of time for this, but if there's no one else who's ever done anything like it, I'll help.
I assume you want to go with JDK 1.3 rather than trying to stick with the MS JVM.
Girder only allows one plugin per DLL. So, I assume that Girder sees one plugin and Java sees many. The alternative would be to have multiple DLLs, which would all be copies of one another, but with some local knowledge of the Java plugin to run. That's a bit of a mess. Even worse, the interface would have to fool with custom classes loaders to get the various implementations in.
Use the registry to tell it what Java code to load. For instance, have a list of .JAR files. In the manifest of each .JAR, have something that gives the fully qualified class names of the Java plugin(s). Maybe allow .JAR files without any plugins for utility classes, in case Class-path in the manifest doesn't work in the regular JVM.
I assume the interface hides all the details of Girder's objects and memory allocation. So, there's a method to set a string field of a command. The cheapo alternative would be to pass some things around as Java longs. I've found that to be a bit of a mess.
So, at init time the Java plugin is instantiated with a reference to an object that wraps all the Girder support functions.
For generating events, probably it doesn't matter which Java plugin it came from once it gets over to Girder. They all look to come from the one device number.
For actions, the Java plugin is passed a reference to an object that wraps the Girder command structure.
Inside Girder, the command needs to identify which Java plugin it belongs to. Perhaps steal one of the string members for this.
An alternative to passing a command with three (two once one is taken away) strings, three Booleans, three integers, and three links would be to pass a Serializable that the interface would take care of storing. Then there would need to be a special wrapper for a link that could be gotten from the tree at edit time and called at execution time.
MMcM
October 13th, 2002, 12:55 PM
I found a bit of time to type in the necessary JNI code. See what you can make of the attached. It should be enough to implement some kind of dispatcher in Java on top of. There will probably need to be adjustments to the C++ code depending on how the class path is maintained. Almost anyone who has MSVC and downloads the JDK could probably do those.
[Edit: Moved to the developers download page because of attachment size limitations.]
MMcM
October 13th, 2002, 12:55 PM
Did you unzip the file attachment to get the DLL or just copy it as downloaded? It should be 50K+; if it's half that, that's the problem.
The JAR and javadocs didn't fit. I figured that anyone who could make use of them would have a JDK.
PM your email address and I'll send you the whole thing as I built it here.
MMcM
October 13th, 2002, 12:55 PM
JVM.DLL is in jre\bin\hotspot for 1.3 and jre\bin\client for 1.4, at least for me. Use the Explorer or dir /s to find it and adjust Girder's AppPath accordingly.
Yes, it is loading the VM itself. It needs to run Java code in the Girder process space. There is no existing JVM, so it needs to create one.
DLLs that only implement native methods don't need JVM.DLL. Anything that starts Java does. Often that's an EXE, but there's no reason it cannot be a DLL. And no reason that DLL cannot also implement native methods. And no reason that DLL cannot also be a Girder plugin.
MMcM
October 13th, 2002, 12:55 PM
The complete ZIP file is now on the Developers download page, where file size is not as much of an issue. The version there also has an official Girder plugin number.
frdfsnlght
October 13th, 2002, 12:55 PM
Has anyone written, or does anyone have a Java version of the plugin API? I'm not sure how it would work, but I imagine it would be a dll that provided a JNI (Java natice interface) to Java code.
I'd like to contribute to the effort, but I don't "do windows". I'm a Java guy by profession and I've designed many a GUI with features that would be very useful as plugins for Girder (HTPC interface stuff).
If no one has done this, would someone like to try and help me do it? I don't have access to VC++ or any MS tools and I haven't looked at the Girder API (yet). Could someone help me compile/test C stuff. I'll do the Java stuff, and maybe we could get a Java plugin working?
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
Wow, I guess there is some interest in this.
MMcM: Your basic description is what I was thinking except I was visuallizing a Girder Java Plugin (call it a "bridge plugin") that presents the Girder API, through JNI, to a Java based plugin that manages all the Java plugins (call this the "Java plugin manager", or JPM). When a user clicks the "Settings" button for the bridge (i.e., actual Girder plugin), it passes the request directly to the JPM which opens it's settings window (a Swing thing) and allows management of plugins (from jar files) and their classpaths, etc. I imagine all the plugins could run in the same VM, but maybe use seperate VMs as a future enhancement, it required.
Like you indicate, the bridge would look like a single plugin to Girder and to use individual Java plugins, you'd probably have to sacrifice one of the arguments to tell the PM which plugin to route to.
Does this sound reasonable? Are we talking about the same basic design?
I'll admit I don't have any experience with JNI beyond reading the tutorials, but it doesn't seem too bad. My main question about it is how this whole system would work together. I think it would work like this:
1) Girder is started.
2) Girder loads its plugins, which actually loads the plugin DLLs.
3) Girder starts each plugin.
4) When the bridge plugin is started, it starts the JPM as a seperate OS process.
5) The JPM calls System.loadLibrary to load and link to the bridge DLL (Girder plugin), but it's already loaded (by Girder).
6) Messages and event flow.
7) When Girder tells the bridge to stop (during unloading of plugins?), it tells the JPM to shutdown, which tells each Java plugin to shutdown.
I'm a little fuzzy on how DLLs work in Windows and how "shared" they are. Is what I'm describing how it would work, or am I way off base?
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
Mark: I suppose each Java plugin could get assigned a "real" Girder plugin number, but that may be confusing to users. I imagine they'd have to pass that as an argument to the "normal" plugin call to send a message to a Java plugin through the bridge and JPM (in addition to the plugin number of the bridge). But I suppose it's no less confusing that having a seperate "name" for each plugin and having to use it in the same way.
On a "Girder guts" related note, I, personally, want to use this whole Java idea to do some GUI interface stuff. I assume I'll want to display the contents of Girder registers in various ways. While I can certainly query Girder for the values of these registers on every repaint, that will get very inefficient, very quickly. Does Girder support the concept of register "listeners"? I'm sure if any of you know anything about Java GUI programming, listeners are a familiar concept:
A client (i.e., a Java plugin that wants to use a Girder register value as a text label in a window) registers itself as a "listener" of the register in question. This is basically a callback setup. When the register is changed, through whatever means, all of it's "listeners" are notified of the change (by Girder, not the plugin). In this case, the client can update it's cached value and force a repaint of the GUI.
An extension of this idea, useful in my experience with systems similar to Girder's register bank, is the idea of "transactions", but not in the sense of "commit" and "rollback" (but maybe). More in the sense that notifications to listeners are supressed until the updater has completed changing many related registers. The idea is to present a consistent view to the listeners. I can elaborate more if necessary.
Does Girder have this ability? If not, can it be added to the API? It's a [fairly] simple change that's backwards compatible with the current API since it's just a set of new functions and doesn't change any of the existing register functions.
Of course, Ron shouldn't be reading this as he should be attending to his sister.
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
When you get a chance (yeah, right) please export the listener interface. Others can worry about how it maps to Java. I already have some ideas.
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
MMcM: Amazing. I hadn't expected something so complete, so soon.
I'll give this a try soon (when I get a few free moments, work seems to be picking up). I expect a minor struggle since I've never written a Girder plugin, so even the API wrapped in Java is a bit foreign to me at the moment. I hope Ron's API docs are up to snuff. I'll post when I have something useful to say about it. Thanks.
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
MMcM: There's no jar file in the stuff you attached. I can make one from what you've provided, but I'm not sure if it should contain anything like a special manifest file.
I'll give it a go with what you've provided. If it doesn't work, I'll need the whole package emailed to me.
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
OK, I compiled the Java source (I didn't make any changes in the "TODO" parts), built a JAR file, put it in the Girder32 directory, put the DLL in the plugins directory, added the java bin to the path for Girder.exe (using the [modified] registry file), and started Girder. I get this error before the main Girder window opens:
"The application or DLL C:\Program Files\girder32\Plugins\GirderJava.dll is not a valid Windows image. Please check this against your installation diskette."
I click "OK" (but it's not OK), and get:
"Could not load C:\Program Files\girder32\Plugins\GirderJava.dll"
I click "OK" (but it's still not OK), and Girder's main window open. Needless to say, the GirderJava plugin doesn't appear in the plugins list.
I'm using:
WinXP Pro
Girder 3.2.4
J2SDK 1.4.0_01-b03
What next?
frdfsnlght
October 13th, 2002, 12:55 PM
That would explain it. The browser I was using was confused about the file names upon download, so I guessed the first was the DLL (no zip) and second was a zip. I'll give it another try.
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
Sorry it took so long to try again; had a busy weekend.
OK, so I renamed the GirderJava.dll to .zip and pulled out the real GirderJava.dll and put it in the plugins directory. I start Girder and get this message:
"This application has failed to start because jvm.dll was not found. Re-installing the application may fix this problem."
I click OK and get this:
"Could not load C:\Program Files\girder32\Plugins\GirderJava.dll"
Click OK and the main Girder window opens.
So I guess the plugin is looking for jvm.dll, which I don't have. Is that part of the JRE you're using? I'm using a 1.4 Java install, so maybe there's a problem there. I'm certainly not up on JNI stuff, but I wouldn't have expected the DLL it to try to load the VM itself. What's the DLL trying to do?
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
OK. I understand now. From what little I understand of JNI, I knew this was possible, but I didn't realize until now that's what you did.
I've got it working now. I can successfully open a settings dialog for the plugin and a command. Now I've got to organize my thoughts and actually build a Java plugin to play with. Thanks!
-Tab
frdfsnlght
October 13th, 2002, 12:55 PM
I don't see any reason why a hardware plugin wouldn't work, but if you'd read this entire thread, you'd see there may be other issues, not related specifically to a hardware plugin, but any Java plugin.
The main one that comes to mind is the issue of plugin IDs. The Java plugin has a single ID as any other Girder plugin would. If you write a plugin with what's provided (graciously by MMcM), it would be identified by the Java plugin ID. and probably not allow any other Java plugins to be used.
I had it in my mind to write a Java-Plugin-Plugin that would provide a framework for multiple Java plugins so each could have it's own ID (outside the scope of Girder's plugin IDs). This single plugin would be a wrapper around MMcM's work and provide it's own interface to other Java plugins in a traditional (i.e., pure) Java manner (ala listeners, and what-not).
Alas, some other projects of mine have been taking much more time than expected lately and I haven't been able to write any of this yet. Of course, anyone else is welcome to take it on if they'd like.
If you want to write a Java hardware plugin now, I'd say go for it. Don't worry about the wrapper I had in mind. In the least, you'd provide more testing of MMcM's code and maybe uncover additional required functionality. If and when someone implements what I'm talking about, I doubt it would be difficult to adapt your plugin to a new interface.
-Tab
crazysquirrel
October 13th, 2002, 12:55 PM
I'm considering writing a hardware plugin in java. Is this possible with the Java version of the plugin API?
Powered by vBulletin® Version 4.1.8 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.