My hobbyist coding updates and releases as the mysterious "Mr. Tines"

Tuesday 19 February 2008

PassiveFTP 1.11

Here or here.

PassiveFTP 1.11 — build 1.11.2971.37821 — mitigates the upload rate problem I've been having, by doing some unexpectedly effective tweaks to socket parameters.

This came after having do do some throughput optimizations on XP at work for code that worked just dandy on Windows server OSs from NT4 up. There it was just a case of upping the send buffer size. Here, that was ineffective, but I did get a big boost from by sending only small packets and disabling Nagle coalescence.

The new default upload rate is 128kb/s (1ms sleep between successful sends of 128-byte packets), which gave the best rate for me, up from an old and unreliable 2kb/s.

This will of course feed back into the FePy version whenever I get the enthusiasm for doing all the plumbing.

Monday 4 February 2008

If only...

Ultimately, the big splat from yesterday tracks down to calling the stub of


JbImp error: Couldn't find class 'java.lang.InheritableThreadLocal'

from the class constructor of Console$. Now it would not be beyond the wit of man to emulate that new class in a library shim and leave everything else as I found it, but... More annoying are the extensions to fundamental classes dating back to JDK 1.0 days, especially final ones like String


JbImp error: Unresolved Method 'public static java.lang.String java.lang.Character.toString(char)'
JbImp error: Unresolved Method 'public static java.lang.String[] java.lang.String.split(java.lang.String)'

where (absent some incantation to splice J#'s AWT into the namespace of an OpenJDK dll or similar), tackling it means modifying the Scala library code to retrofit. Oh, yes, and even then there are some places where the Scala bytecode manages to throw jbimp for a wobbly.

But if I keep to a fairly restricted subset (and for the moment I'd be interested in using it when writing a parser of OpenPGP), I might get away with a very small port of the runtime and library.

Oh, well, like I said, hands on.

Sunday 3 February 2008

Under my nose all the time

Another of those hidden things about J# -- the JbImp tool, which takes .class files and spits out J# assemblies. Just what I wanted, but was looking in the general freeware community for.

Now the full scala-library.jar has a lot of post-J# Java API calls, but by cutting out a lot of the code I can get

>"\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\Jbimp.exe" /t:library /usestubrefs /out:scala-lib.dll /recurse *.class

to work on the remainder of it, and then

>"\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\Jbimp.exe" /t:library /usestubrefs /r:..\JavaLayer.dll ..\scala-lib.dll /out:SClass.dll /recurse *.class

And then build an IronPython project against it and get…

>PythonLayer.exe
In class com_ravnaandtines.jlayer.JClass1.doSomething(), printing from Jython
11
In class com_ravnaandtines.jlayer.JClass1.doSomething(), printing Hello Babel!
Traceback (most recent call last):
  File scala-lib, line unknown, in .cctor
  File vjslib, line unknown, in checkAndThrowException
  File src\Program.py, line 24, in Initialize
  File , line 0, in NonDefaultNew##27
  File , line 0, in .ctor##29
  File SClass, line unknown, in .ctor
SystemError: The type initializer for 'scala.Console$' threw an exception.

which is progress, and most of what the JVM version does; but as this

    private int len;
    private JClass1 in = new JClass1();

    public SClass(String token)
    {
        len = in().doSomething(token);
        Console$.MODULE$.println(BoxesRunTime.boxToInteger(len()));
    }

is the relevant part of the SClass code decompiled, the failure means that although it has executed some Scala derived code, it has fallen over at the first sniff of runtime.

I hope that a more measured winnowing of the runtime will fix this. But not tonight.

No love for client-side Java

It seemed a nice idea, having a deeper stack than just Python on Java that could build cross-VM apps from one code-base. But alas…

  • The only Java-on-.Net runtime I've found that has even half-way decent support for client-side apps (enough of AWT to support the GWT, or any flavour of Swing) is MSFT's J#, especially at 2.0
  • The obvious cross-compilers (scala-net, if I could get it to work; IKVM) want to use anything else they can except the J# runtime, and don't offer the facility to choose the one you want
  • Meanwhile scala's bytecode is just plain beyond decompilation to Java by obvious decompilers

So, I'd have to write the tools myself if I want to do this. It wouldn't even be a simple fork of IKVM to re-point references, and there are also its own special attributes decorating the classes. It might be simpler to tweak the scala compiler, since the .Net-bit islooked smaller in that (and it would improve my hands-on with the language).

 

Later:

Building a replacement scalaruntime.dll based on the .Java files from the scala-library source jar (one tweak for the older Java dialect with doesn't have the JDK 1.4 Character.toString()), plus a J# version of scala.runtime.SymtabAttribute based on the C# one in SVN, easy. Finding that the scala compiler source jar omits all the MSIL compiler files (from https://lampsvn.epfl.ch/trac/scala/browser/msil/trunk), more of a pain.

With a mscorlib 2.0 and my new runtime, and the predef.dll moved out of the way, I have to figure out why System.String is causing a wobbly:


java.lang.RuntimeException: PEModule.getTypeDefOrRef(): TypeSpec
        at ch.epfl.lamp.compiler.msil.PEModule.getTypeDefOrRef(PEModule.java:206)
        at ch.epfl.lamp.compiler.msil.PEType.loadInterfaces(PEType.java:309)
        at ch.epfl.lamp.compiler.msil.Type.initInterfaces(Type.java:944)
        at ch.epfl.lamp.compiler.msil.Type.getInterfaces(Type.java:907)
        at scala.tools.nsc.symtab.clr.TypeParser.parseClass(TypeParser.scala:88)
        at scala.tools.nsc.symtab.clr.TypeParser.parse(TypeParser.scala:58)
...
java.io.IOException: type 'System.String' is broken

I'd probably have to rework a whole lot of stuff that shims a virtual Java library layer. Which would have to start with identifying and encapsulating the shimming.

Friday 1 February 2008

One step forwards...

Based on the helpful comment on my last post, I can run IKVM against 2.0 assemblies, but hit a different obstacle -- a critical failure linking against the J# runtime, leading to a bug report.

It seems to run OK auto-binding to the OpenJDK, but then I need to frob the reference somehow. Perhaps it is back to the scala-net class loader issue...

Le sigh

Later...

I wondered. We won't have much of Swing, but do we have enough of AWT to run the GWT? So I converted TestGadget.jar and gwt221.jar and put all the images and .dlls into the same folder and ran it and...

>TestGadget.exe
Exception during event dispatch:
cli.System.NotImplementedException: The method or operation is not implemented.
        at cli.ikvm.awt.NetComponentPeer.createImage(Unknown Source)
        at java.awt.Component.createImage(Component.java:2522)
        at dtai.gwt.Gadget.createImage(Gadget.java:2045)
        at dtai.gwt.ImageGadget.validateImage(ImageGadget.java:255)
        at dtai.gwt.ImageGadget.paintForeground(ImageGadget.java:283)
...

and while much of the applet showed, the (re-)paint behaviour was terrible, and the applet could easily get into a state where it was spinning at almost 100% CPU.

Le sigh²