… and yet it took me some time to get them all into place 😉
I finally managed to package a headless Seaside Image with GLORP persistence. And what’s even better: it does indeed run and connect to a database and read and update data!
But the process of getting there was a little bit tricky, because in a headless image, you cannot fire off a debugger and look at what’s wrong. You need a little bit of luck and crystal ball reading knowledge and of course a few logging statements here and there to see what might be missing in the image. Interestingly, the headless packaged image on Windows had been running much more easily, and packaging for Linux required more manual loading of code.
So the process is mainly: Package in an 😄 image, start the image and see how far you get. Look at the error messages and try to find out in a development image what could be missing, go back to the 😄 image, load it and see if you get any further.
Most of the time, such an iteration starts (and ends) with a little bit of shouting a few unfriendly words to yourself, something along the lines of “you stupid basterd, had you just thunk a little, everybody out there, including the guy who put the ketchup on your fries this lunch break, knows that you have to include that stuff by hand! Who gave you a diploma and how much did you pay for it”.
But unfortunately, all depression I thus provoked in my head didn’t hinder me from stumbling over the next one just 145 seconds later (that’s about the time it takes to correct such a problem when you have 2 VMs open in parallel).
First of all: when Packaging GLORP headless (maybe even when packaging a normal application), you have to implement the method PackagerClass (with a capital P!) on ProtoObject in GlorpVAPort. If you don’t writing the packaged Image will fail with the message “Included subclasses of nil must implement #PackagerClass”. You may think: hey, that’s really a useful error message and tells you exactly what’s wrong! Right you are, but if you were in my shoes, you’d be puzzled 😉 And this one was exception to the 145 seconds rule…
Then there are a few more things that are so logical it’s hard to believe I didn’t think of them in the first place. There are quie a few classes and Applications that you shouldn’t reduce (add a ruke to the Packaging Instructions):
* I started with DatabasePlatform and the subclasses I needed (AccessPlatform and DB2Platform), but I soon realized it is probably best to simply not reduce any GLORP Applications at all.
* Do not forget to not reduce your Descriptor class, because almost all really important methods are being called by #perform: and most selectors are created at runtime. As I said, it’s obvious and crystal clear, but you have to remember 😉
* If this is an early stage of your project, you probably use a FileLibrary for icons and stuff. Mark it as “do not reduce” or your web pages might look “interesting”.
* After a few hours of fiddling with little problems like this, I was quite convinced I now was at the my goal. All log entries of connecting to the database and starting the WASstServerAdaptor looked good and this must be it. But the gods of Smalltalk showed me one last time that you have to earn your place in the runtime heavens. And it wasn’t yet time for me: 503, Service unavailable, you mortal dwarf! This is the final gate of insight and it is not for you! Not yet! So I had a little chat with the Class Browser and WASstServerAdaptor and SstHttpServletEngine as well as SstHttpServlet and lo and behold: The Packager’s Image Content Browser gave me the Keystone: Both these classes were excluded by Reduction. Interestingly, there was no way of finding out other than guessing and praying.
After that, my application is up and running in an Ubuntu VM without any X windows and stuff, connecting to the Database and working as expected.
So I warned you, there’s nothing new or surprising in this post. Just things you’d never ever forget when you need to package your Seaside application in VA Smalltalk.