JNBridge interoperability tools bridge anything Java to .NET or bridge anything .NET to Java. JNBridge interoperability tools bridge anything Java to .NET or bridge anything .NET to Java.

Archive for the 'Tips and examples' Category

JNBridgePro and Windows 7

Saturday, Aug. 29th 2009

A number of our users have begun using Windows 7. You’ll be happy to know that JNBridgePro works fine with Windows 7, with a few caveats. Here’s where things stand with the current version (4.1.0):

32-bit JNBridgePro: 32-bit JNBridgePro works just fine with Windows 7. The product installs smoothly, and the proxy generators work, as do the Visual Studio and Eclipse plug-ins. The only caveat is that if you are using shared memory and Java 6, you might see a message that contact with the Java side could not be made because msvcr71.dll is missing. This is actually a well-known issue with Java (see detailed discussion of the problem here), and is the result of some very questionable design decisions by Sun; it has nothing directly to with JNBridgePro. The solution to the problem is to find a copy of msvcr71.dll (you can find one in the JDK 1.6′s bin folder), and place it in \Windows\System32 (or \Windows\SysWow64 if it’s a 64-bit operating system). When that is done, the problem will go away. Finally, all applications that use JNBridgePro will work fine; if the applications use shared memory and Java 6, add msvcr71.dll as described above.

64-bit JNBridgePro: In the 64-bit version of JNBridgePro, the installer will show an error when installing the Visual Studio plug-in. Simply hit the return key to pass through this error. If both Visual Studio 2005 and Visual Studio 2008 are on the machine, you will see this error twice. Once the installation completes, the standalone proxy generators will work fine, although the Visual Studio plug-ins will not be installed. All applications that use JNBridgePro will work without problem.

By the time of the release of Windows 7 (scheduled by Microsoft for October 22, 2009), we plan to release a new v4.1.1 of JNBridgePro that will address the two issues discussed above.

Posted by JNBridge | in Tips and examples | Comments Off

JNBridgePro and Eclipse 3.5 (Galileo)

Saturday, Aug. 29th 2009

In the JNBridgePro documentation for the Eclipse plug-in, it only mentions support up through Eclipse 3.4 (Ganymede). However, the JNBridgePro Eclipse plug-in also supports Eclipse 3.5 (Galileo). Install and use it in the same way as you would with previous versions of Eclipse, and everything will work just fine.

Posted by JNBridge | in General, Tips and examples | Comments Off

More about JNBridgePro and the new daylight savings time rules

Friday, Feb. 9th 2007

There’s a very interesting problem with Microsoft’s DST patch for Windows that you should be aware of, since it can impact date conversion results when mapped date proxies are used.  The patch applies the new rules for whether date and time are daylight savings time without regard to year.  This means that if you ask .NET whether a given DateTime in the past is DST, it will apply the new rules even if the date would have been standard time under the old rules.

Consider November 1, 2006.  It was not DST.  However, had the new rules been in effect at the time, it would have been DST.  Now consider the following code:

DateTime date = new DateTime(2006, 11, 1);
bool isDST = date.IsDaylightSavingTime();

If the DST patch has been applied to your system, then isDST will be true, which is incorrect.

What does this mean for JNBridgePro?  It means that, for those dates in the past for which the old and new DST rules conflict, then use of mapped date proxies will cause conversion of dates to be off by one hour in certain cases.  It will only happen with dates in 2006 and earlier, and will only happen during a two-week period in March/April and during a one-week period in October/November.  If you are using mapped date proxies to convert future dates, or are using by-reference proxies for dates, you will see no problem, as long as you have updated your Windows and Java according to the instructions mentioned in the previous post.

We are looking into things that can be done, but there may not be much we can do, since JNBridgePro relies on the underlying .NET and Java  for its DST information and is relying on that information to be correct.  If you have an application that relies on conversion of times from past years, you may want to add your own logic to correct the conversions during those periods in past years where Windows’ DST information is incorrect.

Update: While historical DST information does not exist in Windows XP, it does exist in Windows Vista.  We will look into incorporating this historical DST information in an upcoming version of JNBridgePro.  In the meantime, if you’d like to add logic to your applications to handle historical DST information, please see the following references:

Posted by JNBridge | in Tips and examples | 1 Comment »

JNBridgePro and ClickOnce

Friday, Nov. 10th 2006

There was an interesting support issue here the other day, asking how to use JNBridgePro-enabled application with ClickOnce.  Let’s say you have a nice WinForms app that contains a Java Swing component:

sample Swing component embedded in a WinForms app

Now, let’s say you want to publish the application to a Web site, so that users can employ ClickOnce to download, unpack, and run the application on demand.  You’ll need to add additional files to the project that aren’t actually referenced in the .NET code: in this case, the unmanaged files JNBJavaEntry.dll and jawt.dll (that need to be in the execution folder), plus the Java-side components jnbcore.jar and bcel-5.1-jnbridge.jar, and any Java files that need to be in the classpath that aren’t on the target machine.  (These Java files need to be jar files; the ClickOnce mechanism doesn’t seem to be able to reconstruct Java folder hierarchies.)  The project, with the added files, might look like this:

Project in Solution Explorer

For each of these additional files, you’ll need to make sure that the “Copy to Output Directory” property is set to “Copy Always”:

Properties

You also need to make sure that the configuration file uses relative paths that reference the current runtime folder:

Configuration file

Then, build the application and publish it.  You now have a self-contained application that can be downloaded from a Web server and launched using ClickOnce.  That’s all there is to it.

It’s still necessary to have a JNBridgePro license installed on the target machine if you want the application to run past the end of the 30-day evaluation period.  An upcoming version of JNBridgePro will have the ability to package a deployment license file with the downloaded application.  Let us know if that’s a feature of interest to you.

Posted by JNBridge | in Tips and examples | Comments Off

Callbacks (part 3)

Monday, Sep. 18th 2006

In the third part of our series on callbacks, we’ll discuss what to do if we have a .NET assembly that implements callbacks using a Java-style listener interface.  Since JNBridgePro only supports the delegate/event callback style in Java-to-.NET projects, we need to have a way to convert between the two styles.  Here’s one such way.  Assume we have the following listener interface:

public interface MyCallbackInterface
{ 
    bool myCallbackMethod(int param1, string param2);  

}
 
and the following callback generator class public class CallbackGenerator
{
 
    public static void registerCallback(MyCallbackInterface theCallback) {…}  

    public static void fire() {…}
}
 
We can create .NET event-style wrappers that can be proxied as follows:
public delegate bool MyCallbackHandler(int param1, string param2);  

public class NewCallbackGenerator
{
    // this is the wrapper to convert listeners to events
 

    private class MyCallbackHandlerWrapper : MyCallbackInterface
    {
        MyCallbackHandler mch;
        public MyCallbackHandlerWrapper(MyCallbackHandler mch)
        {
            this.mch = mch;
        }
  
        public bool myCallbackMethod(int param1, string param2) 
        {   

            return mch(param1, param2);
        }
    }
  
    // here is the event interface 
    public static event MyCallbackHandler MyEvent 
    {  

        add
        {
            MyCallbackHandlerWrapper mcw = new MyCallbackHandlerWrapper(value);
            CallbackGenerator.registerCallback(mcw);
        }
    }
  
    public static void fireEvents() 
    {   

        CallbackGenerator.fire();
    }
}
 
You should proxy and use MyCallbackHandler and NewCallbackGenerator as you would any other proxied delegate/event-style callback.

 

 

 

 

 

 

 

 

 

 

 

Posted by JNBridge | in Tips and examples | Comments Off

Callbacks (part 2, at long last)

Monday, Sep. 18th 2006

It’s been a while since I’ve blogged (hey, we’ve been busy :-) ).  I think the best place to pick up is with the long-promised second part of our article on callbacks.  In the first part, I wrote about how to register .NET classes as listeners for Java events (in .NET-to-Java projects).  In this post, I’ll talk about how to write Java classes that can be registered as listeners for .NET events (in Java-to-.NET projects).

Let’s start by describing the .NET event generator class:

public delegate void MyEventHandler(string message);public class EventGenerator
{
     public event MyEventHandler myEvent;
         public void fireEvents(string message)
     {
          myEvent(message);
     }
}
The first thing to note is that our .NET event generator class uses events and delegates, rather than Java-style listener interfaces.  This is the typical .NET style, and it can be confusing at first if you’re used to Java listeners.  Because this is the encouraged .NET style for callbacks (and the way that the .NET Base Class Library does it), it’s the style we support, too.  (In the next callback post, I’ll discuss how to create Java callbacks for .NET classes that use listener-style callback interfaces.) The above code includes a delegate type to represent the event handler, and an event (of that delegate type) as part of the event generator class.  There’s also a method used to fire all the registered events.To register an event handler in .NET, we typically create a method:public void sampleEventHandler(string message)
{
    
Console.WriteLine(“sample event handler: message = “ + message);
}

then designate it as a delegate and add it to the event:

myEvent += new MyEventHandler(sampleEventHandler);

then, when fireEvents() is called, all such methods added to myEvent will be called.Since delegates and events don’t exist in Java, we need to handle them in a somewhat different way on the .NET side. Start by proxying EventGenerator and MyEventHandler.  Include supporting classes. MyEventHandler is proxied as an interface.  It has one method, Invoke(), whose signature is identical to that of the underlying delegate: void Invoke(string);

void Invoke(string);Our Java callback class must implement MyEventHandler:

public class CallbackClass implements MyEventHandler
{
     // method implementation required by MyEventHandler
     public void Invoke(String message)
     {
          System.out.println(“callback fired: message = ” + message);
     }
}

The event myEvent in EventGenerator is proxied on the Java side as a pair of methods, add_myEvent() and remove_myEvent(), which are called to add or remove an event handler.

In our Java code, we instantiate EventGenerator (by instantiating its proxy), then instantiate CallbackClass and register it with myEvent.  We can do this because CallbackClass implements the proxied delegate MyEventHandler.

  // create the event generator
  EventGenerator eg = new EventGenerator();
  
  // register an event handler
  eg.add_myEvent(new CallbackClass());

Now, when we call eg.fireEvents(), all the registered event handlers will execute, including all Invoke() methods of registered Java-side event handlers.

Note that, just like in the .NET-to-Java situation, in Java-to-.NET projects the .NET side will suspend when it calls the Java-side callback and wait until it returns, in order to preserve the expected callback semantics. As in the .NET-to-Java situation, this can sometimes lead to deadlock, particularly in cases involving multi-threaded applications and GUIs. In the previous callback post, we discussed how this problem was addressed in .NET-to-Java projects through use of the [AsyncCallback] attribute. In Java-to-.NET projects, we do something similar: Java callback classes, in addition to implementing their proxied delegate interfaces, can also implement the marker interface com.jnbridge.jnbcore.AsyncCallback, which has no methods. When the .NET side calls a Java callback object implementing AsyncCallback, it doesn’t wait for the callback method to return, but rather continues on. This means that values returned by asynchronous callbacks, and exceptions thrown by them, are ignored.  

Posted by JNBridge | in Tips and examples | Comments Off

Callbacks (part 1)

Tuesday, Apr. 4th 2006

Customers sometimes come to us saying they have a .NET-to-Java project, and asking how they can pass a real .NET object to a method in the proxied Java object. Often they’ll subclass a proxy or implement a proxied interface, but when they actually pass the .NET object to the proxy, they get an exception. I explain that what they really are trying to do is to implement a callback: the .NET code has called the Java side, and during that execution, the Java code “calls back” some .NET object that’s previously been registered as a “callback.” If you’re familiar with Java listener interfaces, you’ll know how this all works.

Callbacks are easy to implement. In this post, we’ll discuss how to implement a callback in a .NET-to-Java project. In the next post, we’ll discuss callbacks in Java-to-.NET projects.

Let’s start with a Java class that allows other classes to register themselves as listeners for particular events, then notifies those listeners that those events occur. All listeners must implement a particular listener interface, which must have at least one method that will be executed when the event occurs. The method can take parameters, and can return values or throw exceptions. Here’s a listener interface:

// this is Java
public interface MyListener
{
   public void fireEvent();
}

Now that we’ve got the listener, here’s the event generator class we’ll be working with:

// this is Java
public class MyEventGenerator
{
   private static java.util.ArrayList listeners = new java.util.ArrayList();

   public static void registerListener(MyListener aListener)
   {
      listeners.add(aListener);
   }

   public static void fireListeners()
   {
      for(int i = 0; i < listeners.size(); i++)
      {
         MyListener aListener = (MyListener) listeners.get(i);
         aListener.fireEvent();
      }
   }
}

If we've proxied the MyListener and MyEventGenerator classes, we can implement .NET classes that can register themselves with MyEventGenerator as listeners:

// this is C#
[Callback("MyListener")]
public class DotNetListener : MyListener
{
   public void fireEvent()
   {
      Console.WriteLine("event fired!");
   }
}

Note that DotNetListener implements the proxied MyListener interface. Also note that it has the [Callback] attribute. These both are essential. The [Callback] attribute's class is really com.jnbridge.jnbcore.CallbackAttribute, so you'll need to make sure you've imported that namespace into your program (using the import (if VB.NET) or using (if C#) keywords). The [Callback] attribute needs the fully-qualified name of the interface, so if the interface is in a package, or if it’s nested inside another class, you’ll need to supply the entire name. Also note the method fireEvent() that any class implementing MyListener must implement.

Now we can use DotNetListener wherever a proxy expects a MyListener:

// this is C#
MyEventGenerator.registerListener(new DotNetListener());
MyEventGenerator.fireListener();

The console will now print “event fired!”.

Callbacks can take parameters, return values, or throw exceptions, but the parameters, return values, and exceptions must be of classes that the Java side “understands,” which means they need to be proxies, primitives, strings, or arrays of those.

A callback class can implement multiple listener interfaces, but if it does, you’ll need to annotate the callback class with a [Callback] attribute for each listener interface it implements.

One subtlety to be aware of is that when the Java side calls the callback, the Java thread doing the calling suspends until the callback returns. This is done to preserve the expected callback semantics. Since the Java thread has suspended, it’s likely that the .NET thread that originally called the Java side has suspended, since it’s waiting for the Java side to return. Usually this is fine and expected, but sometimes, as when you’re using the callback inside a Windows Form, it can lead to deadlock. To get around this problem, use an asynchronous callback, which is designated using the [AsyncCallback] attribute rather than the [Callback] attribute. When an asynchronous callback is called, the Java-side thread doesn’t wait around until the callback returns, but goes on its way. This avoids the deadlock issue. The tradeoff is that since the Java side doesn’t wait around for the result of the callback, asynchronous callbacks can’t return values or throw exceptions.

That’s all there is to callbacks! In our next post, we’ll explain how callbacks work in the opposite direction: in Java-to-.NET projects.

Posted by JNBridge | in Tips and examples | Comments Off

DNDJ article on constructing a BizTalk Server/JMS adapter using JNBridgePro

Monday, Mar. 13th 2006

We’ve written an article on how to construct a BizTalk adapter for JMS using JNBridgePro, that’s just been published in the .NET Developers’ Journal (volume 4, issue 3).  You can see it here.

Update: The article’s now out in hardcopy. See p.10 of DNDJ (volume 4, issue 3).

Posted by JNBridge | in General, Tips and examples | Comments Off

Embedding Java GUI components in .NET GUIs

Wednesday, Mar. 1st 2006

Update:  We’ve released JNBridgePro v3.1, which incorporates the support libraries described below, which makes embedding Java GUI components in .NET GUIs even simpler.   See the announcement here.  The 3.1 installer includes a version of this example targeted toward 3.1.

In my last post, I showed how to embed a .NET GUI component inside a Java GUI. In this post, I’ll show the inverse: how to embed a Java GUI component inside a .NET GUI.  We probably see more requests for this direction than for the other, since more customers have Java GUI components that they want to use in new .NET programming than the other way around.  As in the last post, after showing how to embed the Java component in the .NET GUI, we’ll show how you can have the .NET GUI react to events in the Java component.

Start by downloading the sample code. In addition to the sample code, there are a couple of dlls and jar files containing helper classes that assist in the interop. These helper classes will eventually be included in the JNBridgePro runtime components themselves, but in the meantime, you can use these assemblies when creating your own GUI interop projects.

We’ll start with a Java component in JavaComponent.java, that looks like this:

Java GUI component

Note that the control has several parts, including a label, a text box, and a button. The text box and its contents can be accessed through a field, and there is a method to register an ActionListener that will be called when the button is pressed.  The control has been compiled, and is called jInN.JavaComponent.

The proxies have already been generated and are in the file javaComponentProxies.dll. If you want, you can re-create the proxy dll by launching the proxy generation tool and creating a new .NET-to-Java project. Add jInN.JavaComponent to the classpath, then load jInN.JavaComponent plus supporting classes, and generate proxies for all the classes.

Next, we examine the .NET GUI-based application in Form1.cs. We’ve included a WinForms Panel that will hold the Java component. Note the simple code sequence inside the constructor:

// create the Java GUI component
JavaComponent jcp = new JavaComponent();
// register any callbacks
jcp.addActionListener(new DotNetActionList(jcp.javaTextBox, dotNetTextBox));
// wrap it so it can be embedded
jc = new JavaControl(jcp);
// embed it
javaHolder.Controls.Add(jc);

First, create the Java control by instantiating its proxy. Next, register callbacks; we have a .NET-side implementation of ActionListener that, when fired, will get the contents of the Java textbox and copy it to the .NET textbox. Once the Java control has been set up, we wrap it in a special wrapper class DotNet.JavaControl.  JavaControl is derived from System.Windows.Forms.Control, and contains the linkages necessary to embedding the Java component in the .NET control. We then add it to the enclosing Panel.

That’s all that’s needed to embed a Java component inside a .NET GUI.

Open the .NET solution provided and build it.  You may need to adjust the references to jnbshare.dll and jnbsharedmem.dll. In our example, you’ll want to use the .NET 2.0-targeted version of these components. Also make sure that the various file paths in the app.config file are correct for your computer.

Finally, find a copy of jawt.dll in the jre\bin folder of your Java development kit or the bin folder of your Java runtime environment and copy it to the folder into which your built project has been placed. Also copy the file jnbtools.dll into that folder.

Running the .NET application, we see this:

Java component embedded in .NET GUI

And that’s all there is to embedding a Java componet in a .NET Window. When we fill the Java text box and click on the button, the event fires and the .NET-side callback is executed, copying the text into the .NET text box.  You can make more complex interactions, and even have bidirectional communications between the .NET and Java GUI elements.

The key to the interop is the JavaControl wrapper class. Once you instantiate the Java component’s proxy and wrap it, you can plug it in wherever a WinForms component would go.

As I mentioned before, to do any embedding now, use the helper assemblies and jar files; in the future, they will be incorporated into the JNBridgePro runtime components.

We’d love to hear from you about this.  Let us know if you try it, and if you see a use for it in your upcoming projects.

Posted by JNBridge | in Tips and examples | Comments Off

Embedding .NET GUI components in Java GUIs

Thursday, Feb. 16th 2006

Update:  We’ve released JNBridgePro v3.1, which incorporates the support libraries described below, which makes embedding .NET GUI components in Java GUIs even simpler.   See the announcement here.  The 3.1 installer includes a version of this example targeted toward 3.1. 

One feature request we frequently get is for a way to embed .NET GUI components in Java GUIs, or, conversely, to embed Java GUI components in .NET GUIs.  In this post, we’ll show you how to put a .NET component inside a Java GUI, and to have the Java GUI react to events in the .NET component.

Start by downloading the sample code. Unpack the zip file. In addition to the sample code, there are a couple of dlls and jar files containing helper classes that assist in the interop. These helper classes will eventually be included in the JNBridgePro runtime components themselves, but in the meantime, you can use these assemblies when creating your own GUI interop projects.

We’ll start with a .NET control in JNBControl.cs, that looks like this:

.NET control

Note that the control has several parts, including a label, a text box, and a button. The text box and its contents can be accessed through a field, and there is a method to register a delegate that will be called when the button is pressed.  The control has been compiled, is called JNBTest.JNBControl and is in the assembly JNBTest.dll.

The proxies have already been generated, and are in the file dotNetControlProxies.jar.  If you want, you can re-create the proxy jar file by launching the proxy generation tool and creating a new Java-to-.NET. Add JNBTest.dll to the assembly list, plus the assemblies System and System.Windows.Forms from the GAC (either the .NET 1.1 or 2.0 versions, depending on which version you’re using). Then, load JNBTest.JNBControl plus supporting classes, and generate proxies for all the classes.

Next, we examine the Java GUI-based application in javaTest\MainClass.java. This is a simple AWT-based application. Note the simple code sequence in the middle of the main() method:

// create the .NET control
JNBControl c = new JNBControl();
// register any callbacks
c.registerClickDelegate(new ClickEventHandler());
// wrap it so it can be embedded
DotNetControl dnc = new DotNetControl(c);
// size it
dnc.setSize(224, 104);
// embed it
f.add(dnc, dncConstraints);

First, create the .NET control by instantiating its proxy. Next, register callbacks; we have a Java-side event handler that, when fired, will get the contents of the .NET textbox and copy it to the Java text box. Once the .NET control has been set up, we wrap it in a special wrapper class com.jnbridge.embedding.DotNetControl. DotNetControl is derived from java.awt.Component (actually, java.awt.Canvas, which is a subclass of Component), and contains the linkages necessary to allow embedding of the .NET control in the Java component. We then size it like any other AWT component, and add it to the enclosing frame using graphical constraints that have already been prepared.

This is all that’s needed to embed a .NET component inside a Java GUI.

When compiling, make sure the build classpath contains the proxy jar file and the helper jar file jnbtools.jar, as well as the usual jnbcore.jar and bcel-5.1-jnbridge.jar.

Finally, let’s run the program. Note that GUI component embedding will only work with shared memory communications.  Make sure that jnbshare.dll, jnbsharedmem.dll, and jnbjavaentry2.dll are in the GAC. Also, make sure that jnbtools.dll and jnbtools.jar are together in the same file. Finally, examine jnbcore_sharedmem.properties. Note that we are loading JNBTest.dll and JNBTools2.dll, as well as System.Windows.Forms. Make sure that all paths in the file are correct for your machine.

To run the application, make sure that the classpath contains all the files in the build classpath. You can use runJava.bat, but first make sure that all the paths are correct for your machine.

Running the application, we see this:

Embedded .NET GUI component in a Java app

Yes, that’s really a .NET control inside a Java AWT window!  When we fill in the .NET text box and click on the button, the event fires and the Java-side callback is executed, copying the text into the Java text box. You can make more complex interactions, and even have bidirectional communications between the .NET and Java GUI elements.

The key to the interop is the DotNetControl wrapper class.  Once you instantiate the .NET control’s proxy and wrap it, you can plug it in wherever an AWT component would go.

As I mentioned before, to do any embedding now, use the helper assemblies and jar files; in the future, they will be incorporated into the JNBridgePro runtime components.

We’d love to get your feedback on this. How many of you see a use for it?

In an upcoming article, we’ll go in the other direction and show how to embed Java GUI components in WinForms.

Update: that new article, on embedding Java GUI components in .NET GUIs, has been posted.

Posted by JNBridge | in Tips and examples | 2 Comments »