Showing posts with label jni4net. Show all posts
Showing posts with label jni4net. Show all posts

Wednesday, September 24, 2014

jni4net 0.8.8 - release

Changes

  • [#35] - fixed - Integer overflow on 64-bit OS [by Geert Claeys]
  • reworked contributed code to become full owner of the code and be able to change license.
  • changed runtime license to MIT. Tools still GPLv3.
  • moved to github and jni4net.github.io
  • changed documentation to MarkDown and improved a bit. Links to new issue tracker and stackoverflow.
  • removed support for publishing jni4net to maven repository on google code.
  • Hope that community would enjoy the freedoms of MIT license and github and would fork it and contribute back :-)

    Download here

    Monday, September 19, 2011

    jni4net 0.8.6 - release

    Changes

    • fixed permission demand for sandboxed environments
    • improved proxygen can't find class reporting
    • improved the way we are looking for jni4net.j-xxx-.jar (while installed in GAC)
    • [#27] - fixed build script problems
    Download here

    Road map

    May people asked for road map. This is my vision, not a promise.

    Wednesday, August 17, 2011

    jni4net 0.8.5 - release

    Changes

    • [# 9] - support for indexer properties [by Johannes Rudolph]
    • [#22] - Potential field name clash due to increasing numbering strategy of field names
    • [#24] - Change of current directory during init may disrupt other code running in parallel
    • [#25] - DirectByteBuffer doesn't work with Java 7
    Download here

    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

    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

    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)
    

    Saturday, April 17, 2010

    jni4net NOT yet on Mono & Linux

    I started with investigations of support for Mono on x86. The key problem is different calling convention - cdecl. My current implementation of JniLocalHandle is build on top of assumption that small structures are put onto stack same way as scalar types. But that's not valid assumption, it works just for stdcall. cdecl allocates the structure on heap and passes just pointer to the structure, no matter how big the structure is. Why I created JniLocalHandle ? Because I wanted to make strongly typed difference between JniLocalHandle and JniGlobalHandle. We could drop it and use IntPtr in order to deal with this problem. It will impact all generated proxies on C# side.
    There is another problem with cdecl, because I need to put
    [UnmanagedFunctionPointer(CallingConvention.xxx)]
    on any JNI delegate. Example is JNIEnv.AllocObject. I think I'll need to duplicate whole JNIEnv class in order to avoid condition for each call.
    Last small problem is with JNI.Dll which has the main
    [DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]
    , it must be duplicated as well, because there is jvm.so on Linux.

    Currently I don't hear from people that they need Mono/Linux support for jni4net. If you think you need it, please tell us the use case. I'm interested to hear why Mono support is worth of the effort. Till then I put it on ice.

    jni4net version 0.8 for .NET 4.0

    • added support for CLR v 4.0
    • v40 is now loaded by default if it could be found. You could set the version explicitly with Bridge.setClrVersion()
    • #8 added BridgeSetup.AddJVMOption(string)
    Download jni4net 0.8

    Wednesday, March 3, 2010

    jni4net 0.7.1 - small bugfix release

    Bug fixes

    • [#7] - added ParPrimC2J(IntPtr)
    • [#5] - Reading Java home location from the Windows registry (Contributed by Martin Matula), BridgeSetup extended with JavaHome, and improved JavaHome auto detection
    • fixed missing assembly version for jni4net.n.*.dll

    Saturday, February 13, 2010

    jni4net version 0.7 released

    support for delegates and events

    .NET events and delegates are supported by proxygen and runtime. From Java side they could be invoked with Invoke() method which has proper signature. Delegates could be also implemented on Java side, by usual anonymous class and passed back to CLR. So Java could subscribe to .NET events.
    this.button1.addClick(new system.EventHandler(){
            public void Invoke(system.Object sender, system.EventArgs e){
                button1.setText("Clicked");
            }
        });
    
    Full code is in winforms sample, which is part of binaries.

    Other changes

    • solved problem with spaces in path to dll/jar
    • assembly loading now uses java.io.File or assembly name (breaking change)
    • static class is no longer found by name, attribute parameter added (breaking change)
    Download there

    Sunday, January 24, 2010

    jni4net version 0.6 released

    • Implemented out and ref parameter from C#
    • DateTime.TryParse has second parameter 'out'. This is how to use it from Java:
      Out<DateTime> dt=new Out<DateTime>();
      if (DateTime.TryParse("2009-08-28",dt)){
          System.out.println(dt.getValue());
      }
      

    • Improved proxygen to not generate virtual method overrides
    • Eliminated lot of warnings in generated code
    • Strongly typed JNI references (this is breaking change, please regenerate your proxies)
    • Sun specific DirectBufferCleaner, which holds the reference to pinned buffer
    • Native methods unregistration when appdomain unloads
    • Switched off signed .jar, because it prevents other people generating (unsigned) proxies into same packages. For example java.util_
    • Possibility to specify alternate classloader
    • Declarative security for running in partially trusted environments
    • JVM exceptions are serializable for CLR binary serialization
    Download there

    Friday, December 4, 2009

    jni4net version 0.5 released

    Second public release of jni4net is out. New features are:
    • Simplified proxygen to wrap all classes in DLL or JAR file from command-line, without time spent on config file. It as well provides very simplistic build.cmd. I will write another article about proxygen soon, till then look at new samples.
    • Ported java.nio.ByteBuffer to .NET, so you could share same byte array in both VMs. You are able to use BinaryWriter in .NET as well, but same byte order and interface is more convenient.
    • There are new Adapt.Enumeration and Adapt.Disposable methods on CLR side. They are convenience adapters from corresponding Java interfaces.
      foreach (var prop in Adapt.Enumeration(javaSystemProperties.keys()))
      {
          cnt++;
      }
      
      using (var fis = Adapt.Disposable(new FileInputStream(classPath)))
      {
          using (var zis = Adapt.Disposable(new ZipInputStream(fis.Real)))
          {
              ZipEntry entry = zis.Real.getNextEntry();
              while (entry!=null)
              {
                  string name = entry.getName();
                  entry = zis.Real.getNextEntry();
              }
          }
      }
      
    • Improved proxygen code generator
    • Few minor bugfixes
    • New troubleshooter page
    Download there

    Tuesday, November 3, 2009

    How calling from Java to .NET works in jni4net

    Tonight I would like to explain how calling from Java to .NET works with jni4net. The other way around is described in previous article, it would be good if you read that first if you didn't yet.

    So, in JNI there is method which allow you to register native implementation of Java method. Such method had "native" keyword in it's signature. I believe that it's actually how low level methods in Java runtime are implemented.

    We use proxygen tool, which is part of jni4net, to reflect any public members of .NET type and then to generate Java proxies. Those proxy methods are marked native. The generator must do few translations to follow Java naming rules. Namespaces are always lower-cased to become packages. Properties are converted to bean-like get and set methods.
    jni4net JVMProxy

    For exceptions the situation is similar. system.Exception proxy is inherited from Java java.lang.RuntimeException to be throw-able. Therefore it isn't inherited from system.Object proxy. But there is system.IObject interface on both of them for your convenience.

    The proxy implements Java finalizer, so when JVM GC cleans up the proxy instance, the real CLR instance is released as well. The reference to CLR is implemented as GCHandle converted to long and kept on JVM side inside the proxy.

    system.Object proxy as well overrides toString() method and forwards it to CLR. It seems that in version 0.4 I forgot to override hashCode() and equals(), sorry about that ;-)

    The implementation is is asymmetric to CLR->JVM proxies, because for both it's CLR which does the translation work. The wrapper have signature which is expected by JNI RegisterNatives. I apply Marshal.GetFunctionPointerForDelegate to wrapper methods to get endpoint callable by JVM. Side note is that JNI RegisterNatives does not make any difference between static and instance methods. They are identified by name and signature only, strange limitation.

    Last trick I mention is about initial CLR bootstrap. During initial design I realized that there is way how to export native method from managed DLL. So I currently use that trick to create DLL with signature friendly to JVM. It seems to me now, that I will need to change my approach soon in order to support multiple versions of CLR and Mono on Linux. Probably I would need to use C++/COM. For now, we have 32bit and 64bit CLR 2.0 on Windows.

    Next time maybe about interfaces and type casting.

    Saturday, October 31, 2009

    How calling from .NET to Java works in jni4net

    In this article I would like to explain how calling from .NET to Java works with jni4net.

    First of all you should know that Java Virtual Machine (JVM) is exposing Java Native Interface (JNI). It is native/binary interface which allows other programs to control JVM: load classes, create instances and run methods. It as well allows you to control object lifetime by holding handle to instance. Usual way how to consume JNI interface is to use %JDK%\include\jni.h in your C++ program and then load jvm.DLL. I wanted solution for .NET, so I use [DllImport] attribute and I translated the header file from C to C#. I also converted all pointers and handles to IntPtr. So now we have JNI interface accessible to any .NET code.

    Now it's quite easy to use JNI methods to call Java objects, but it's far from convenient. So the next step was to use Java reflection and get signatures of core objects and generate proxies. The proxies look like Java classes, they have same name, namespace, same methods with same signatures. But it don't have the implementation in .NET but rather they call the real implementation in JVM using JNI. The reflection and proxy code generator is reusable idea, so I created 'proxygen', it's tool which is part of jni4net package. You could use it to wrap your own classes.
    jni4net JVMProxy

    Now you should know few tricks. JNI calls are done on handle of the method, which could be retrieved by method name and signature. See javap. To make it faster, I pre-bind the proxy-class to real-JVM-class during start-up.

    To make the proxy good citizen in .NET world, java.lang.Object overrides Equals(), GetHashCode(), ToString() .NET methods and forward the calls to appropriate Java equivalent. You should be aware that there could be multiple proxies for same Java instance. java.lang.String proxy implements implicit conversion to CLR String.

    Because we need garbage collection work, proxy implements finalizer. When CLR garbage collector finds lonely proxy, we release JNI handle of the real Java instance, so it could be collected on JVM side as well. Warning, it is possible to create cycle between objects across both heaps, which would prevent GC from collection. I have no good solution for that now, just be careful.

    Another feature to mention is exceptions. To make Java exceptions useful in CLR, they should be inherited from System.Exception. Simply to be able to throw and catch them in .NET. But it means that they could now be inherited from java.lang.Object proxy. This is compromise, but it's worth of it, because now you could catch exceptions thrown by Java method in .NET code because jni4net does transparent translation for you. You will receive proxy of exception. To overcome the problem with common base class, I introduced java_.lang.IObject interface with all expected methods.

    Last note would be about call marshalling. It's done with PInvoke on CLR side and with JNI on JVM side. The primitive types are very well compatible. Unsigned types from CLR are transmitted binary. Strings are translated as Unicode, it's bit slow. Any other non-primitive parameter is Java object. Which means you need to pass another proxy/Java object as parameter (for brevity we ignore interfaces now). When returning from the call, we could have return value. It is the way how to send Java instances back to .NET. jni4net/proxy wraps the JNI handle for you. It finds best-fit proxy-class and returns its instance. The proxy contains JNI handle to the real Java instance.

    Next time about calling back from JVM to .NET and proxies of CLR objects in Java.

    Saturday, October 10, 2009

    jni4net - bridge JVM and CLR

    jni4net
    I'm proud to present first public release of jni4net - Object oriented, fast, intraprocess bridge between JVM and CLR.

    Hello World!

    From C# to Java
    using net.sf.jni4net;
    public class Program
    {
        private static void Main()
        {
            Bridge.CreateJVM(new BridgeSetup());
            java.lang.System.@out.println("Greetings from C# to Java world!");
        }
    }
    
    This is very basic demonstration of the principle, full version of this sample and another 3 sample applications could be found in binary distribution. The others are same Hello World but from Java to .NET, usage of Apache FOP from C# for xsl:fo and last is creation of WinForms dialog from Java.


    Please download here and talk back.

    Next time I will write about why I created it, how it works, what are the features and what are the next steps. Watch this space.