Tuesday, June 28, 2011

jni4net 0.8.4 - release

Changes

  • Added ability to load proxies into specified classLoader by Jose Chillan.
    Bridge.LoadAndRegisterAssemblyFromClassLoader(File, ClassLoader)
  • JNIEnv.DetachCurrentThread() contributed by Renier B.
  • Bridge.setClrVersion() made static by Leonid Bogdanov
Download here

Saturday, March 26, 2011

Raising Property Changed fast and safe - yet another solution

This Thursday we discussed with my colleagues how to raise property changed event. We learned that it could be done
a) via string literal,
b) via lambda expression tree,
c) via StackTrace or MethodBase.GetCurrentMethod().
Nice summary is here. or here

We did some naive performance test and learned that for 500k iterations on simple property, there is big difference in speed.
a) is really fast, 13ms
b) is slow, 1417ms, I guess because security checks apply for every call and every stack frame, and can't be fired from other properties.
c) is slow, 2518ms, very slow, because expression tree is constructed for every call

So we played with it for a while and I invented solution with anonymous type (at botom).

Update 27.3.2011: I was so focused on speed that I didn't realized that the solution yesterday didn't work nicely for rename. What a shame. I hope people give me another chance today. Here we have postponed creation of the expression tree, it takes about 75ms. And this time my ReSharper renames it correctly :-)
Update 5.12.2011: As Alex noted in comments, there was thread safety issue with Dictionary. The code is now fixed with Hashtable instead.


public abstract class ModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private static readonly Hashtable Names = new Hashtable();

    protected void RaisePropertyChange(Func<string> key)
    {
        if (PropertyChanged != null)
        {
            var propertyName = (PropertyChangedEventArgs)Names[key];
            if (propertyName==null)
            {
                propertyName = new PropertyChangedEventArgs(key());
                lock (Names)
                {
                    Names[key] = propertyName;
                }
            }
            PropertyChanged(this, propertyName);
        }
    }

    protected static string Reg<T>(Expression<Func<T>> property)
    {
        return (property.Body as MemberExpression).Member.Name;
    }
}

public class Model : ModelBase
{
    private string firstName2;
    public string FirstName2
    {
        get { return firstName2; }
        set
        {
            firstName2 = value;
            RaisePropertyChange(() => Reg(() => FirstName2));
        }
    }
}

Doesn't work: The lambda just helps to define the type without creating the instance and calling the getter. It takes about 77ms for half million calls.

public abstract class ModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private static readonly Dictionary<Type, PropertyChangedEventArgs> Names = 
          new Dictionary<Type, PropertyChangedEventArgs>();

        protected void RaisePropertyChange<T>(Func<T> f)
        {
            if (PropertyChanged!=null)
            {
                var key = typeof(T);
                PropertyChangedEventArgs evntArgs;
                if (!Names.TryGetValue(key, out evntArgs))
                {
                    var propertyName = key.GetProperties()[0].Name;
                    evntArgs = new PropertyChangedEventArgs(propertyName);
                    lock(Names)
                    {
                        Names[key] = evntArgs;
                    }
                }
                PropertyChanged(this, evntArgs);
            }
        }
    }

    public class Model : ModelBase
    {
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set {
                if (firstName != value)
                {
                    firstName = value;
                    RaisePropertyChange(() => new {FirstName});
                }
            }
        }
    }

Sunday, February 20, 2011

jni4net 0.8.3 - release

Changes

  • added support for IBM JRE
  • added drools sample
  • added BridgeSetup.IgnoreJavaHome
  • improved error logging during initialization

Blocked DLLs for CLR 4.0

If you download the distribution package on jni4net and unzip it via Windows Explorer, it will set the DLL security zone as untrusted. That will prevent CLR 4.0 from loading the DLL and you will receive exception while initializing jni4net from Java side.
The message states:
Can't init BridgeExport:An attempt was made to load an assembly from a network l
ocation which would have caused the assembly to be sandboxed in previous version
s of the .NET Framework. This release of the .NET Framework does not enable CAS
policy by default, so this load may be dangerous. If this load is not intended t
o sandbox the assembly, please enable the loadFromRemoteSources switch. See http
://go.microsoft.com/fwlink/?LinkId=155569 for more information.

You can solve it by unblocking the DLLs.
Right-click on the files, open file properties and click unblock button.

Sunday, January 2, 2011

jni4net 0.8.2 - bugfix release

Bug fixes

  • upgraded nMaven, NUnit, made build 32bit only
  • fixed throwing exceptions for missing proxy classes
  • [#18] - C# string[]{null} -> JVM -> null reference exception
  • improved architecture detection

Sunday, November 7, 2010

jni4net 0.8.1 - bugfix release

  • Fixed memory leak reported by Jaco Ackermann
  • Included improved CLR detection contributed by Leonid Bogdanov
Download 0.8.1 here

Thursday, September 23, 2010

Decomposition in functional languages

Got an idea: functions (in FP) could be composed similar was as components in OOP. For example with dependency injection. For components in OOP we use interfaces. For functions we could use delegates. To achieve decomposition and modularity.
I tried to find something about it. No luck. Probably because there are no functional programs big enough to need this ?
While searching for enterprise scale applications written in FP I found this list. Functional Programming in the Real World and this paper

I hope I just missed the killer application for FP, which would be big enough to deserve decomposition. Maybe someone could find me answer at stack overflow.

Tuesday, July 20, 2010

CLR 4.0 for Robocode

I finally got motivated by Justin and Jason to do something for Robocode .NET again. I upgraded it to jni4net 0.8. This means Robocode will prefer CLR 4.0 if installed and then will run robots written in C# 4.0 or F#. I also implemented Robocode Control API for .NET. I piggyback to Flemming's working branch, hope he will not kill me once he returns from holidays :-D

Download preview is there, Alpha quality.
robocode-1.7.2.2-Alpha-setup.jar
robocode.dotnet-1.7.2.2-Alpha-setup.jar

MyFirstRobot.F#

I really like the syntax.
namespace SampleFs
open Robocode
type MyFirstRobot() = 
    inherit Robot()
    override robot.Run() = 
            while true do
                robot.TurnLeft(40.0)
                robot.Ahead(20.0)
    override robot.OnScannedRobot(evnt : ScannedRobotEvent) = 
            robot.Fire(1.0)
    override robot.OnHitByBullet(evnt : HitByBulletEvent) = 
            robot.TurnLeft(90.0 - evnt.Bearing)