Porting Jainja JVM
Pages: 1 2
Guillaume Legris (10341) 11 posts |
Hi, I am the author of the Jainja JVM 1 and saw on the forum that there was some interest in running Java on RISC OS. So I tried and got preliminary results. Things that work well:
Things not tested yet:
Difficulties:
|
Alain Lowet (7745) 41 posts |
Hello Guillaume, |
Steffen Huber (91) 1953 posts |
Welcome! That interest might be a “one person only” thing: me. I had a quick look at Jainja some time ago when looking for portable JVM options, but never had the free time necessary to get into the details. So many thanks that you are doing the grunt work. I think you already had a go a few years ago?
I would still be interested in having a look at test builds if you are prepared to share your work at this early point of develeopment. I guess you are using GCCSDK? Which GCC version?
UnixLib (“the POSIX library”) has code to automatically do that “create directories to simulate extensions” thing, but to be honest, I wouldn’t recommend that, because it introduces all kind of subtle problems all along the way. Just use “/” as an extension separator instead of the usual “.”, and “.” instead of the usual “\” or “/” as a directory separator and disable automatic extension conversion in UnixLib (IIRC, you can set a system variable externally for that). I think this will make it also easier in the long run when you start reading your class files from within jars. |
Guillaume Legris (10341) 11 posts |
Thank you Alain and Steffen for your answers.
Yes but I haven’t managed to set up a practical development environment. I managed to compile but the executable crashed.
Yes: gcc version 4.7.4 (GCCSDK GCC 4.7.4 Release 6)
Sure, a temporary RISC OS package is available in the Downloads section of the project. Some progress: I was able to run complex GUIs using a SDL backend. But they don’t work like they should: the operating system is a bit frozen. |
Guillaume Legris (10341) 11 posts |
After some research I realized I had the same problem with a relatively simple test application in C using SDL. I’m not sure I can fix this in libSDL. So I’ll focus on using Java from the command line for now. I’m still interested in getting feedback on using the test build on real hardware (I am currently developing/testing with RPCEmu) |
Alain Lowet (7745) 41 posts |
Hello Guillaume, when you say hardware, you mean riscos on a raspberry pi (5.28…) or Archimedes/RiscPC hardware ? |
Guillaume Legris (10341) 11 posts |
As Jainja is an interpreter, you need a fairly fast processor, so I was thinking about a Raspberry Pi. For processors below 500 MHz, it’s best to use a JIT or compile Java code ahead of time. I think I could also provide the latter but Java threads won’t work. |
Andrew McCarthy (3688) 605 posts |
It’s looking good. I’ll post back tomorrow with my observations. In the meantime, there’s a NetSurf-friendly link below for anyone who wants to try it. A couple of things come to mind before I go: SCUMMvm and a few Python games (Store- supplier: JVS) use SDL 1.2. |
Andrew McCarthy (3688) 605 posts |
Here are the results, RPi4 (RISCOS daily build 22-Oct-23).
The window’s content is there, but the window itself has issues. I discovered that I can quit the TaskWindow to get control back. In Tetris, you can see the game, but again, the window has issues. And it’s a similar thing with the other examples. I see a Git repository for SDL, which I guess you may already know about. https://github.com/libsdl-org/SDL-1.2/blob/main/README.RISCOS https://www.riscosopen.org/forum/forums/11/topics/17302 The code contained in the preceding links works on my computer with no window issues- saying that it’s not exactly doing much. Good luck, and thank you. |
Cameron Cawley (3514) 157 posts |
Are you able to build specific files with different optimisation levels to the rest of the code? That might help narrow down what’s going wrong.
UnixLib is capable of handling both name/ext and ext.name conventions automatically. Which extensions use which conventions is dictated by an environment variable, but the default behaviour is to use name/ext conventions. You can also turn off path conversion, but that’ll require handling everything yourself. Most of the Acorn-era Java stuff I’ve encountered uses name/ext conventions, so it would make sense for Jainja to do so as well.
It’s quite possible that it’s just too slow at the moment. The important thing to remember is that RISC OS uses cooperative multitasking, so you’ll need to make sure that you call SDL_PollEvents, SDL_Delay or a similar function regularly to make sure that the other tasks get a chance to run. Also, I wouldn’t recommend running GUI applications from a Task Window since that’s never worked very well for me. If you need some way of showing debug messages while the GUI is active, I’d recommend using Reporter instead. |
Guillaume Legris (10341) 11 posts |
Thank you very much Andrew ! It seems to me that this performance is consistent with what one would expect. In this case, a x3 slowdown compared to an x86 processor at the same frequency.
Interesting, how do you do that?
I tried to inspect the RISC OS code in the SDL 1.2 repository but found no solution yet. |
Guillaume Legris (10341) 11 posts |
This isn’t what I’m currently doing but it’s possible so I’ll try.
In pseudo-code, I do this: while(!exit) { wimp_poll(GET_EVENTS_EXCEPT_MOUSE_KEY_WINDOW); exit = vm_tick(); // Execute 1000 bytecodes per thread } When a GUI is started, vm_tick() also runs a dedicated (green) thread to poll GUI events every 50ms using SDL_PeepEvents.
If I redirect the output to null the task window doesn’t show so I assume the JVM is no longer attached to it (?) Thanks Cameron ! |
Andrew McCarthy (3688) 605 posts |
You’re welcome. I quit the Task window by assuming that despite the general lack of response from the system, a click on the close [x] icon might work, and it did. ;) Background reading: Further down the line, I wonder if this means you might be able to re-use some of the existing resource allocations |
Guillaume Legris (10341) 11 posts |
From this comment from Cameron and Andrew’s link of a helloworld for SDL (known to work well), I did some tests and can reproduce the issue:
So I did the same thing for the JVM, and voila, the problem disappeared ! I guess Task Window is interfering with the logic in libSDL somehow. Thank you again for your comments which put me on the path. I don’t know if I would have been able to find the problem alone. Now I’m going to try to optimize all of that and make it easy to use the JVM. |
Steffen Huber (91) 1953 posts |
Very good progress, thank you Guillaume for investing your time into our niche platform. Seeing a Java-based GUI on a RISC OS desktop more than 25 years after Acorn’s “Riscafe Java 1.0.2” efforts goes far beyond my expectations. Very well done. As always, my free time for experimentation is currently very limited, but I promise to do some trials of the “things I always wanted to test if a JVM for RISC OS ever surfaces” kind ASAP. And of course running Jainja on a Windows/Linux JVM also remains on my TODO list. |
Guillaume Legris (10341) 11 posts |
Here is some news. First of all I installed RISC OS on an RPI3 and I use VNC and OmniClient/Samba to have a faster development cycle. I tried to figure out why GCC’s optimization flags weren’t working. After numerous tests, I had some progress:
This optimized version (but limited by the absence of a garbage collector) is approximately 3x faster. On the RPI3, an application with a simple AWT GUI takes about 2 seconds to start. In the package I will put both versions:
|
Andrew McCarthy (3688) 605 posts |
Good to hear more about the project, Guillaume. ;) I keep checking the Sourceforge download page for a new release. If you need a soundboard or more information about GCC, the GCC mailing list is at riscos.info. Thanks for the update. |
Guillaume Legris (10341) 11 posts |
I figured out how to fix some GCC optimization flag issues. I put a new version (jainja_riscos_dev_20231120) on SourceForge. There are now 3 versions of the JVM. jainja
jainja-na
jainja-na-armv7
Limitations / bugs:
By editing the !Run file you can try some GUI examples. You could even try a Swing application, but as you probably know, it’s a huge library so don’t expect it to be very fast on an interpreter. |
David J. Ruck (33) 1635 posts |
256MB may sound a lot, but you can multiply by 10 if something like pyCharm is ever going to run on it! |
Steffen Huber (91) 1953 posts |
Guillaume, again thank you for your ongoing effort, it looks like you are making good progress.
I have quite a few home-grown Swing applications that would even make sense running on RISC OS, so this will surely be interesting to see if I can get acceptable speed out of them. Back in the mid-2000s, I did quite a bit of Look’n’Feel benchmarking for a large Swing application, and the differences between the L&F implementations were staggering. I guess in an environment like Jainja, differences would be even more noticable. |
Guillaume Legris (10341) 11 posts |
Yes, I think so too. That’s why I’ve been evaluating different ways to optimize this for several months. Now I think there are two ways to do it:
Currently I’m looking at scenario 2. |
Steffen Huber (91) 1953 posts |
My gut feeling is that the interpreter itself will not be the bottleneck, but the graphics operations. Probably not helped by the SDL layer in this case. ISTR that Synth allowed for custom painters, maybe this could be an interesting optimization knob. But it is certainly an immense complexity you are dealing with here, and good profiling is always a challenge. |
Andrew McCarthy (3688) 605 posts |
I’m unfamiliar with Java and JVMs, so I wonder if it’s possible to run Freemind? Can anyone show how to supply the correct paths and commands to the JVM? |
Paolo Fabio Zaino (28) 1882 posts |
From what I understand, when executing a third-party Java app with jainja, you need to include the Runtime library in the ClassPath. For FreeMind, which requires java/lang/Thread.class, it’s essential to ensure that the rt/jar associated with your jainja installation is accessible. This is where the challenge begins. To simplify this process, I added a !Boot file in !Jainja that defines the Jainja: path. This allows me to easily pass it to all my Java code using -cp. If you’re new to Java, starting a Java application from a zip file is quite straightforward. Here’s how you can do it with jainja: jainja -cp the-zip-file-name.zip TheNameOfTheMainClass Here, -cp stands for Class Path. It can be a series of jar (Java ARchive) file names, like “lib/mylib.jar”;“lib/mylib2.jar”;“lib/mylib3.jar”. Remember, in jainja, use Linux path conventions: / as a separator and .jar as the file extension. TheNameOfTheMainClass refers to the main class from which your app starts. So, regarding the rt/jar, I always include “Jainja:rt/jar” in my run line. This setup has worked well for me and should also be effective for FreeMind. Another important aspect is that Jainja requires a significant amount of memory. To facilitate easy testing, I’ve also added an alias in my !Boot that sets the Wimpslot for Jainja and then runs it with the necessary parameters. This is particularly useful for running large applications like FreeMind. For instance, your run command for FreeMind might look like this: jainja -cp freemind-bin-1.0.1.zip;Jainja:rt/jar; freemind/main/FreeMindStarter Some Java applications require a more customized class path list, usually found in a BAT, Sh, or Bash file within the zip file. However, be cautious with the FreeMind zip file, as it seems to reference jars that aren’t included in the archive. I recommend starting with simpler applications to avoid confusion. When downloading a Java app, it’s generally better to download the jar compatible with all systems, though Guillaume might have additional insights. A word of caution: - jainja currently maxes out CPU usage at 100% for everything I’ve tried, indicating it’s still in early development stages. If you don’t know how to write the appropriate !Boot file to add these simple “fixes” I can share mine. Hope this helps! |
Steffen Huber (91) 1953 posts |
I failed to successfully run an ultra-simple Swing app with Jainja, so I would guess the chances to run something more complex are basically zero. However, I was not able to invest much time to look deeper into it. |
Pages: 1 2