Quick Start Guide

Installing javOnet

Note: Before using javOnet, make sure you have JDK 1.6 or newer and following pre-requisites installed:

For use with .NET Framework 3.5 (supports .NET 3.5 DLLs):
Visual C++ Runtime 2008: x86 or x64 depending on your JDK/JRE architecture.
.NET Framework 3.5: download here

For use with .NET Framework 4.0 (supports .NET 4.0 and 3.5 DLLs):
Visual C++ Runtime 2010: x86 or x64 depending on your JDK/JRE architecture.
.NET Framework 4.0: download here

For use with .NET Framework 4.5 (supports .NET 4.5, 4.0 and 3.5 DLLs):
Visual C++ Runtime 2013: x86 or x64 depending on your JDK/JRE architecture.
.NET Framework 4.5: download here

As javOnet is single file solution, all you need to start using it is to download the latest javOnet jar file into your JAVA project, and add a reference to this file in your build path. Activate method allows you to specify which .NET framework should be loaded. If any of pre-requisites will be missing Javonet will detect them automatically and display in exception message the URLs for download of required dependencies.

How to add the javOnet JAR reference in Eclipse?

  1. Right click on your JAVA project in “Package Explorer”.
  2. Open Build Path > Configure Build Path, choose “Add JARs.
  3. Select the javOnet jar file.

Activating javOnet

Before using javOnet, you must first activate your licence. Your license can be activated in your code using static method activate

To activate javOnet in your code

Note: The “Javonet.activate(…)” method must be called before you use any other javOnet features.

Example

public static void main(String[] args) throws JavonetException { 
	Javonet.activate("your@email.com", "YOUR-LICENSE-KEY", JavonetFramework.v40);
	//Todo: Your javOnet powered application code 
}

Activation must be called only once at the start-up of your application. During the first activation, javOnet contacts our servers and generates a javonet.lic file in your application directory. All subsequent calls simply verify this file.

Last argument of activate method allows you to specify which .NET framework version should be used by Javonet to load your DLLs. Higher frameworks are backward compatible. If you have .NET 4.5 installed you can run Javonet in JavonetFramework.v45 mode and use .NET 3.5, 4.0 and 4.5 DLLs. This argument is of com.javonet.JavonetFramework enum type.

How to activate javOnet using a proxy?

Starting with javOnet v1.3, the activation method allows for new optional arguments which can be used to configure Javonet to activate the license using a local proxy server.

Using these new arguments proxy details, used by Javonet while performing activation, can be specified. Javonet supports any HTTP proxy:

  • Without authentication
  • With authentication
  • With authentication based on Active Directory accounts

In environment where proxy settings are required to access internet these activate method overloads can be used:

activate(String email, String licenceKey, String proxyHost, JavonetFramework framework);

activate(String email, String licenceKey, String proxyHost, String proxyUsername, 
String proxyPassword, JavonetFramework framework);

activate(String email, String licenceKey, String proxyHost, String proxyUsername, 
String proxyPassword, String proxyDomain, JavonetFramework framework);

Specify the hostname and port or IP address in standard formats in the proxyHost field.

  • hostname:port
  • ip_address:port

Note: In environments where proxy settings are required to access the Internet, use these activate method overloads:

public static void main(String[] args) throws JavonetException {
Javonet.activate("your@email.com","YOUR-LICENSE-KEY","myProxyServerHost:80", "proxyUserName", "proxyPassword", JavonetFramework.v40);
//Todo: Your javOnet powered application code
}
Activating javOnet through an XML configuration file

There are many benefits to activating and setting up javOnet using an XML configuration file. It simplifies distribution of your application to your team, lets you update the javOnet license more quickly, and avoids hardcoded activation details.

During the first application use, javOnet searches for, and then automatically uses the XML configuration file to activate your application.

Simply name the file “javonet.xml” and place it in the root directory of your JAVA application .

Sample javOnet XML configuration file

<?xml version="1.0" encoding="ISO-8859-1" ?>
<javonet>
<activation>
    <username>YOUR NAME</username>
    <email>your@email.com</email>
    <licencekey>YOUR-LICENSE-KEY</licencekey>
</activation>
<settings>
    <framework>v40</framework>
</settings>
</javonet>

Starting with version 1.3, javOnet supports proxy settings for activations. These settings can be defined as activate method arguments or as an optional tag in your XML configuration file using the following syntax:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<javonet>
<activation>
      <username>YOUR NAME</username>
      <email>your@email.com</email>
      <licencekey>YOUR-LICENSE-KEY</licencekey>
      <proxy>
           <host>HOST_NAME:PORT</host>
           <username>OPTIONAL_USER_NAME</username>
           <password>OPTIONAL_USER_PASSWORD</password>
           <domain>OPTIONAL_USER_DOMAIN:PORT</domain>
      </proxy>
</activation>
<settings>
    <framework>v40</framework>
</settings>
</javonet>

Adding References to .NET Libraries

JavOnet allows you to use any .NET library. As with any regular .NET application, you need to reference the libraries you are planning to use. You can reference any custom DLL file on your computer or registered in GAC, as well as any library from the .NET Framework.

To add a reference, call the Javonet.addReference(“library_path_or_name”) method.

Example

public static void main(String[] args) throws JavonetException {
	Javonet.activate("YOUR NAME", "your@email.com", "YOUR-LICENSE-KEY", JavonetFramework.v40);

	Javonet.addReference("System.Windows.Forms","System.Drawing");
	Javonet.addReference("yourDotNet.dll");
}

In the addReference argument, you can provide the local DLL file name, the full path or the name of the library registered in GAC. If you plan to reference more than one library, you can pass all of them as arguments, or call addReference several times.

Note: By default javOnet references mscorlib from the .NET framework.

Adding references to .NET libraries through an XML configuration file

There are many benefits to setting up javOnet using an XML configuration file. It simplifies distribution of your application to your team, lets you update the javOnet references more quickly, and avoids hardcoded referenced DLLs details.

Before the first usage Javonet looks for XML configuration file and loads defined references. Using XML references you can still add additional libraries in JAVA code using standard approach.

More about using XML configuration file you will find in Activating Javonet section.

Sample javOnet XML configuration file with DLLs references

<?xml version="1.0" encoding="ISO-8859-1" ?>
<javonet>
<references>
    <reference>System.Windows.Forms</reference>
    <reference>System.Drawing</reference>
    <reference>yourDotNet.dll</reference>
</references>
<activation>
    <username>YOUR NAME</username>
    <email>your@email.com</email>
    <licencekey>YOUR-LICENSE-KEY</licencekey>
</activation>
<settings>
    <framework>v40</framework>
</settings>
</javonet>

Invoking Static Methods

To invoke the static method, first get the particular .NET type and call invoke providing method arguments.

Example how to call static method “Show” on “MessageBox”

	Javonet.getType("MessageBox").invoke("Show","Hello Javonet!");

The invoke method allows you to call any .NET static or instance method with or without arguments. Value-type arguments are automatically translated to appropriate .NET types, and you can also pass referenced arguments as explained later in this guide.

See Live Example!

Creating Instance and Calling Instance Methods

JavOnet lets you create instances of any .NET type. To store reference of a particular .NET object, the javOnet-created NObject JAVA type can be used by variables of any .NET object.

To create an instance of a .NET object, call the Javonet.New method. Once called, you’ve created a reference to that object that could be assigned to NObject variable, which you can then use to perform any operations on that object.

Example

Here’s how to call “Next” method on instance of .NET “Random” class:

	NObject objRandom = Javonet.New("System.Random");
	Integer value = objRandom.invoke("Next",10,20);

	System.out.println(value);

JavOnet calls are very similar to regular .NET or Java calls, with a little bit of reflection style. Value-type results are automatically converted into JAVA types so you can safely assign them to JAVA variables. Reference-type results must be assigned to NObject variable.

Any calls to .NET objects using javOnet can be shortened and simplified using our Fluent interface. To find out more, click here.

See Live Example!

Calling Generic Methods

With javOnet you can very easily invoke any generic instance or static method. To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular .NET types. Let’s assume you have following .NET object you want to use from JAVA:

class GenericSample 
{
    public void MyGenericMethod<T>(T arg1) 
    {
          return;
    }
    public K MyGenericMethodWithTwoTypes<T,K>(T arg1) 
    {
          //Some operation
          return null;
    }
}
// Sample .NET usage
GenericSample genSample = new GenericSample();
genSample.MyGenericMethod<String>("sample");
genSample.MyGenericMethodWithTwoTypes<String,Int32>("sample");

If you want to call MyGenericMethod with type String, you need to use following piece of JAVA code in javOnet:

// (..) initialize javonet + load your .NET dll
//Create new instance of GenericSample class
NObject genSample = Javonet.New("GenericSample"); 
//Invoke generic method with one type
genSample.generic(Javonet.getType("String")).invoke("MyGenericMethod","sample");

//Invoke generic method with two types
genSample.generic(Javonet.getType("String"),Javonet.getType("Int32"))
    .invoke("MyGenericMethodWithTwoTypes","sample");
  1. Create an instance of our GenericSample class.
  2. Using the generic method, initialize the generic method invocation by passing one or many generic types of arguments.
  3. Invoke your method with a sample argument.

Javonet.getType(typeName) returns an instance of NType object attached to a specific .NET type. The instruction NType myType = Javonet.getType(“String”) is the Java equivalent of the .NET Type myType = typeof(String).

See Live Example!

Creating Instance Of Generic Object

Javonet allows you to create instances of generic objects. To initialize generic class first NType with expected generic type should be created. Next to initialize the instance of generic type call the “create()” method on NType object.

Important Notice that while initializing NType for generic class there is apostrophe with number of generic arguments provided which let’s Javonet recognize which generic class should be initialized. For example for List<T> class, the List<Strings> can be obtained by calling Javonet.getType(“List`1″,String”). As first argument we provide generic type name and number of generic arguments and as second argument the name of the type to be used as generic type. If class expects more then one generic type they should be passed as further arguments of getType method.

How to create instance of .NET generic class Dictionary<String,List<String>>

//Initialize List <String> type
NType typeList = Javonet.getType("List`1","String");
//Get String type
NType typeString = Javonet.getType("String");
//Initialize Dictionary<String,List<String>> type
NType type = Javonet.getType("Dictionary`2",typeString,typeList);

//Create instance of generic Dictionary
NObject newDict = type.create();
	
//Create instance of generic List
NObject newList = typeList.create();
//Add items to generic list
newList.invoke("Add","a");
newList.invoke("Add","b");

//Adding items to generic Dictionary passing string as key and generic List as value
newDict.invoke("Add","List1",newList);
newDict.invoke("Add","List2",newList);

//Retrieving dictionary item by string key
NObject result = newDict.getIndex("List1");

//Displaying second item from generic List retrieved from dictionary
System.out.println(result.getIndex(1)); //displays "b"

See Live Example!

Get/Set Values for Static Fields and Properties

With javOnet you can easily get or set a value for any static field or property on a .NET class or structure by calling the “get(fieldOrPropertyName)” or “set(fieldOrPropertyName, newValue)” method on reference to .NET type. Conversely, .NET instance types can be stored in JAVA variables using the dedicated JAVA type called NType.

As with the methods, value-typed results are automatically translated into JAVA types and reference results are returned as NObject objects.

Example

	NType dateTimeClass = Javonet.getType("DateTime");

	NObject nowDateObj= dateTimeClass.get("Now");

	String currentDateString = nowDateObj.invoke("ToString");

In this example we retrieve the value of the static Now field on .NET DateTime class, and store it in the NObject variable named nowDateObj. We then use this object to call ToString method.

Similarly, you can call set on any .NET static field or property:

//Your .NET class
	public class JavonetSample
	{
		public static int MyStaticField { get; set; }
	}
//Usage in JAVA
	NType sampleType = Javonet.getType("JavonetSample");
	sampleType.set("MyStaticField", 10);
	Integer val = sampleType.get("MyStaticField");

See Live Example!

Get/Set Values for Instance Fields and Properties

To set or get values of instance fields and properties, get or create an instance of the .NET object, and call “get(fieldOrPropertyName)” or “set(fieldOrPropertyName,newValue)” methods on NObject containing this field.

Example

//Your .NET class
	public class JavonetSample
	{
		public int MyInstanceField { get; set; }
	}
//Usage in JAVA
	NObject sampleObj = Javonet.New("JavonetSample");
	sampleObj.set("MyInstanceField", 10);
	Integer val = sampleObj.get("MyInstanceField");

See Live Example!

Passing Reference-Type Arguments

With javOnet, you can very easily pass any .NET object as argument to any .NET method, or substitute a .NET field or property. Instances of .NET objects can be stored in your JAVA application using the special NObject type variable. When passing the NObject object to the .NET method, Javonet just pass it as a reference.

	NObject size = Javonet.New("System.Drawing.Size");
	size.set("Width", 500);
	size.set("Height", 100);

	NObject label = Javonet.New("System.Windows.Forms.Label")
	label.set("Size", size);

As you see you can create an instance of the Size object, set its “Width” and “Height” properties, and pass it into the Size property on the Label object. This way you can pass the object as an argument to any method or field and property.

Example

	NObject nowDateObj= Javonet.getType("DateTime").get("Now");

	NObject date = Javonet.New("DateTime",1980,1,1);
	NObject datesDiff = nowDateObj.invoke("Subtract",date);

Here the “Now” field gets a value from DateTime. Then we create a new DateTime value, passing a date of 1980-01-01 as constructor arguments, then we subtract these dates. The datesDiff variable will store an instance of the TimeSpan object that holds the difference between now and 1980-01-01.

See Live Example!

Passing Arguments by Reference with “ref” and “out” Keywords

Microsoft .NET allows you to create methods that expect arguments to be passed by reference. Passing by reference is introduced by explicitly setting ref or out keywords before argument type within the method definition. For example, void MyMethod(ref int arg1).

Note: Passing arguments by reference should not be confused with passing reference-type arguments described in the previous section. If you need just to pass another .NET object in method arguments, please see the previous section.

JavOnet allows you to pass by reference both .NET objects (NObject) or primitive types (String, Integer, Float, Boolean etc..). You can also pass arrays of these types like NObject[] or String[].

While passing variables by reference, the value of that variable might be modified within the method body. Read more about .NET ref and out keywords here:

JavOnet allows you to invoke methods expecting “ref” or “out” arguments by providing two dedicated types: NRef and NOut. To pass the variable by reference, you must wrap the variable with the NRef or NOut class. For NObject and NObject[], you can wrap them with NRef or NOut directly. However because JAVA does not support passing by reference primitive types, both variables (like String, Integer, Boolean etc.) or arrays of them should be wrapped with the “AtomicReference” class, and then wrapped with NRef or NOut object.

Example .NET object with expecting “ref” argument method

class RefExample
{
	public void Method(ref int i)
	{
		i = i + 44;
	}
}

Example of a “ref” argument method from JAVA using javOnet

 NObject refEx = Javonet.New("RefExample");
 //Wrap Java integer in AtomicReference to allow passing by reference
 AtomicReference<Integer> myInt = new AtomicReference<Integer>(10);

 refEx.invoke("Method",new NRef(myInt));

 System.out.println(myInt.get());
 //Output will display number "55" because int passed by reference has been modified within the method body.

See Live Example!

Example of a Int32.TryParse (string arg, out int number) method from JAVA

 String strNumber = "4";
 AtomicReference<Integer> myInt=new AtomicReference<Integer>();

 //NOut constructor with argument type is used because myInt has NULL value. Without specifying explicitly 
 //argument type .NET would not be able to locate proper method to execute.
 if (Javonet.getType("Int32").invoke("TryParse",strNumber,new NOut(myInt,"System.Int32")))
 {
 	System.out.println(myInt.get());
 }

Example of an “out” argument method to populate an array of custom .NET objects

 
class Item 
{ 
     public String ItemName { get; set; } 
} 
class PopulateItems 
{ 
     public void Populate(out Item[] items) 
     { 
           items = new Item[5]; 
           for (int i=0; i<5; i++) 
           { 
                items[i]=new Item(); 
                items[i].ItemName="Item"+i.ToString(); 
           } 
     }
}

Example of a populate method passing items in an array with an “out” argument

The populate method expects to pass an items array with an “out” argument. Therefore the items array does not need to be initialized before calling the method, and after execution, the passed variable will be filled with items.

 
NObject populator = Javonet.New("PopulateItems"); 
//Wrap null JAVA array in atomic reference to pass the reference as out argument
AtomicReference<NObject[]> items = new AtomicReference<NObject[]>(null);

populator.invoke("Populate", new NOut(items,"Item[]"));

//After execution of this method local items array variable will contain five items generated within Populate method body.

See Live Example!

Passing typeof(Type) as Method Argument

If target .NET methods expects “Type” as argument, which is being called in .NET using Method(typeof(Some_Type)) syntax, you can call such method with NType object as argument.

Javonet introduces “NType” class to store .NET Type. To retrieve the instance of particular .NET type as counterpart of typeof(String) you should use Javonet.getType(“String”) method. The “getType(String typeName)” method is static method on Javonet class which accepts in first argument the name of .NET type and returns the instance of NType class connected to the Type object of provided type. Type name argument might contain either type name or type name with full namespace. If there is only one type with selected name in loaded assemblies then Javonet will lookup the namespace automatically otherwise full namespace should be provided or exception will be thrown.

How to pass typeof(Type) as method argument

Sample method in .NET

public void PassTypeArg(Type myType)
{
        Console.Out.WriteLine(myType.ToString());
}

Usage in JAVA

NObject sampleObj = Javonet.New("Sample");
		
sampleObj.invoke("PassTypeArg",Javonet.getType("String"));
//or
NType typeOfString = Javonet.getType("String");
sampleObj.invoke("PassTypeArg",typeOfString);

See Live Example!

Using Nested Types

Nested types are the classes defined within other class or struct. Javonet is able to create the instance of nested type, pass nested type as Type argument, set nested type to field or property and use nested types as generic arguments for methods and classes.

More about nested types you can read in MSDN documentation: http://msdn.microsoft.com/en-us/library/ms173120.aspx

Sample of nested type

namespace MyApp 
{
    public class Container
    {
        public class Nested
        {
            Nested() { }
        }
    }
}

To reference nested type with full namespace the name of the nested class should be prefixed with namespace, name of parent class and “+” sign. For example the “Nested” class defined above could be access using following path “MyApp.Container+Nested”. Following examples show how to initialize and work with nested types using full namespace.

Important: If nested type class name is unique within the loaded assemblies, you can use just the class name. For example “Nested” and work with it as it was regular type.

Sample of using nested types in JAVA with full namespace

//Getting nested type
NType nestedTypeObj = Javonet.getType("MyApp.Container+Nested");

//Creating instance of nested type
NObject nestedTypeInstanceObj = Javonet.New("MyApp.Container+Nested");

//Passing nested type as method argument
sampleObj.invoke("MethodWithTypeArg", nestedTypeObj);

//Creating generic object with nested type as generic argument
NObject genList = Javonet.getType("List`1",nestedTypeObj).create();

//Calling generic method with nested type as generic argument
sampleObj.generic(nestedTypeObj).invoke("GenricMethod");

See Live Example!

Enums: How to Work With .NET Enum Type

To use .NET enums in your JAVA project, javonet API provides special NEnum type. Using this class you can keep the reference of particular enum value, get/set the enum value, pass the enum value as method argument or compare enum values.

To initialize reference to .NET enum type you can use the NEnum(String enumTypeName, String enumValue) constructor. As first argument you must provide enum type name with or without namespace. When namespace is not provided Javonet will automatically lookup the enum type in all loaded assemblies, if there is only one type with provided name it will be used. In second argument selected enum value should be provided.

How to initialize NEnum object

Sample enum definition in .NET:

public enum SampleEnum 
{
    ValueOne,
    ValueTwo,
    ValueThree
}

Enum usage in JAVA:

//Create instance of enum value
NEnum sampleEnumValueOne = new NEnum("SampleEnum","ValueOne");

//Display enum value name
System.out.println(sampleEnumValueOne.getValueName()); //displays "ValueOne"

//Display enum value
System.out.println(sampleEnumValueOne.getValue()); //displays "0"

How to get/set enum value and pass enum as method argument

Sample code in .NET

public enum SampleEnum 
{
    ValueOne,
    ValueTwo,
    ValueThree
}
public class Sample
{
     public SampleEnum EnumField { get; set; }
     public void MethodA(SampleEnum value)
     {
          Console.Out.WriteLine(value);
     }
}

Usage in JAVA

NObject sampleObj = Javonet.New("Sample");  
  
//Set enum as property value  
sampleObj.set("EnumField",new NEnum("SampleEnum","ValueTwo"));  
 
//Get enum from property  
NEnum enumValue = sampleObj.<NEnum>get("EnumField"); 
		
System.out.println(enumValue.getValueName());
System.out.println(enumValue.getValue()); 
  
//Pass enum as method argument  
sampleObj.invoke("MethodA",enumValue);  
  
//Check enum value  
if (enumValue.equals(new NEnum("SampleEnum","ValueTwo")))
{  
	 System.out.println("Enum returned from EnumField equals ValueTwo");  
}  
else  
{  
	 System.out.println("Enum returned from EnumField does not equal to ValueTwo");  
}  

See Live Example!

Arrays: Using Value-Type and Reference-Type Arrays

With javOnet, you can use any value-type or reference-type arrays. Arrays can be retrieved from field or property values, returned as method invocation results, or passed as arguments or set to fields and properties. All array operations can be performed both on instance and static elements.

Using arrays is very simple. Value-typed arrays are translated into regular arrays of corresponding JAVA types. Reference-typed arrays are represented as array of NObject objects.

Example

//Sample .NET class
    public class Item
    {
        public string ItemName { get; set; }
    }
    public class Sample
    {
        public string[] GetItems()
        {
            return new string[] { "item1", "item2", "item3" };
        }
        public Item[] GetRefItems()
        {
            return new []{ new Item("Item1"),new Item("Item2"), new Item("Item3")};
        }
        public void DisplayArray(string[] items)
        {
            Console.Out.WriteLine("Displaying value-typed array");
            foreach (var item in items)
                Console.Out.WriteLine(item);
        }
        public void DisplayArray(Item[] items)
        {
            Console.Out.WriteLine("Displaying ref-typed array");
            foreach (var item in items)
                Console.Out.WriteLine(item.ItemName);
        }
    }
//Usage in JAVA
	//Retrieving array of strings
	NObject sampleObj = Javonet.New("Sample");
	String[] items = sampleObj.invoke("GetItems");
	for (int i=0; i<items.length;i++)
	{
		System.out.println(items[i]);
	}

	//Passing array of strings
	String[] stringArray = new String[] {"Item1","Item2","Item3"};
	sampleObj.invoke("DisplayArray",new Object[] {stringArray});

	//Retrieving array of .NET objects
	NObject[] refArray = sampleObj.invoke("GetRefItems");
	for (int i=0; i<refArray.length;i++)
	{
		System.out.println(refArray[i].get("ItemName"));
	}

	//Passing array of .NET objects
	sampleObj.invoke("DisplayArray",new Object[] {refArray});

See Live Example!

Calling Overloaded Method Passing Null Argument

In some cases you might need to call a method – that has multiple overloads with the same number of arguments – passing null. Considering following case:

public void MethodA(String arg)
{
    Console.Out.WriteLine("Method with String argument called");
}
public void MethodA(Object arg)
{
    Console.Out.WriteLine("Method with Object argument called");
}
public void MethodA(int? arg)
{
    Console.Out.WriteLine("Method with nullable int argument called");
}

If you call MethodA passing “null” as argument .NET side will not be able to resolve which method should be called as in both overloads null can be passed. Ambigous invocation exception will be thrown. To overcome this issue Javonet introduces “NNull” type which allows to pass type-specific null value.

How to call .NET method passing type-specific null value

//To call MethodA with String argument passing null use the following syntax
sampleObj.invoke("MethodA",new NNull("String"));

//Or to call overload with generic int? argument
sampleObj.invoke("MethodA",new NNull("Nullable`[System.Int32]"));

See Live Example!

Subscribing to .NET Events

Subscribe to any .NET event with javOnet. Event subscription works the same way as listening JAVA events. The performance of event subscription is extremely high and allows you to interact with .NET code like it was native JAVA code. When the event occurs, your JAVA listener callback is called in a separate thread.

The simplest way to subscribe an event is to use an anonymous JAVA class.

Example

To create a .NET button and listen for a “Click” event:

	NObject button = Javonet.New("System.Windows.Forms.Button");
	button.set("Text", "Click me!");

	button.addEventListener("Click",new INEventListener() {
		public void eventOccurred(Object[] arguments) {
			System.out.println(".NET event occured");
		}
	});

The anonymous class should implement special INEventListener interface. Alternatively you can write a separate class as the event listener by extending NEventListener and overriding the eventOccurred method, or by implementing the INEventListener interface.

//Your custom JAVA listener class for .NET events

	public class MyEventListener implements INEventListener
	{
		@Override
		public void eventOccurred(Object[] arguments) {
			System.out.println(".NET Event Occurred");
		}

	}

//Usage of your listener class

	NObject button = Javonet.New("System.Windows.Forms.Button");
	button.set("Text", "Click me!");

	MyEventListener listener = new MyEventListener();
	button.addEventListener("Click",listener);

See Live Example!

Disposing of a .NET Object

You can integrate the JAVA garbage collector with your .NET objects using javOnet. When you create an .NET object and store it in a JAVA variable, it will be handled in .NET process as long as your variable lives in the JAVA memory.

When JAVA collects the NObject object, this event is passed to .NET, and the corresponding .NET object is disposed and collected. If the .NET object implements the IDisposable interface, then the appropriate disposal procedure is followed.

You can also force object disposal by calling the “Dispose” method on the “NObject” object. javOnet exposes the dedicated “Dispose” method for closing all objects and releasing .NET memory. This method should be called only at the end of your JAVA application.

See Live Example!

Using the javOnet Fluent Interface

javOnet offers a robust fluent interface that lets you simplify and shorten operations on .NET objects.

Example

//Regular code
	NObject nowDateObj= Javonet.getType("DateTime").get("Now");

	NObject date = Javonet.New("DateTime",1980,1,1);
	NObject datesDiff = nowDateObj.invoke("Subtract",date);

	String dateDiffStr = datesDiff.invoke("ToString");

	System.out.println(dateDiffStr); 

//Fluent code
	String dateDiffStr = Javonet.getType("DateTime")
		.<NObject>get("Now")
		.<NObject>invoke("Subtract",Javonet.New("DateTime",1980,1,1))
		.invoke("ToString");
	System.out.println(dateDiffStr);

See Live Example!

Extending the .NET Class in JAVA and Wrapping .NET Methods

You can extend any .NET class by extending the JAVA class with the “NObject” type and then call the constructor base constructor by passing the name of the .NET type and arguments for its constructor as an argument.

Example

Here’s an example of how to extend the.NET System.Windows.Forms.Form class and wrap the ShowDialog method.

public class MyExtendedForm extends NObject {

	public MyExtendedForm() throws JavonetException
	{
		super("System.Windows.Forms.Form");
	}

	public void ShowDialog() throws JavonetException
	{
		this.invoke("ShowDialog");
	}
}

See Live Example!

Batching GC with DelayGcContext

There could be a scenario where huge amount of short living instances of .NET objects are being created on JAVA side. Huge amount is estimated above 500 000 objects per minute. It could be when .NET side triggers event subscribed on JAVA side with many reference-type arguments (NObjects) or when multiple objects are being created for executing business logic calculation in big loops. In each of these cases when memory utilization is increased JAVA garbage collector will quickly start collecting NObject instances. Javonet forwards such calls to .NET side. When there are more then 500,000 collections per minute the overall application performance might be affect by additional GC call for each of the NObject instances.

In such cases the new DelayGcContext class (introduce in Javonet 1.4) could be applied. The best way to determine if DelayGcContext is required is by performing performance tests with suspicious piece of code. DelayGcContext class allows to indicate the beginning and the end of the code for which the garbage collection calls should be batched. The GC buffer for these objects will be flushed to .NET side every time the buffer size exceeds 100 000 objects pending in the queue or when 30 seconds pass.

The beginning of delayed garbage collection section should be indicated by calling static “Begin” method on DelayGcContext class and terminated by calling “End” method as presented on the snippet below:

 DelayGcContext.Begin();
 for (int i=0; i<5000000;i++) {
 	NObject objA = Javonet.New("SampleType",i);
 	NObject objB = objA.get("B");
 	processItem(objB);
 	(... some other operations ...)
 	NObject objC = objB.getRef("subProp").getRef("subProp").invoke("GetC");

        //in this block objA, objB, and objC instance if not referenced in other parts of code
        //will be subjected for garbage collection after each iteration of the loop
 }
 DelayGcContext.End(); 

More about DelayGcContext you can read in our docs section for DelayGcContext class.

Handling .NET Exceptions

Any .NET exception can be handled in your JAVA code. All javOnet methods that operate on .NET objects throw a JavonetException when exceptions occur. You can catch .NET exceptions by catching the JavonetExceptions, and then perform the appropriate exception handling logic.

	try 
	{
		NObject sampleObj = Javonet.New("Sample");
		Integer result = sampleObj.invoke("AddInt",4,5);

		System.out.println(result);
	}
	catch (JavonetException je)
	{
		//Todo: Your exception handling code
	}

See Live Example!

Accessing the .NET AppConfig File (connectionStrings and appSettings)

If your .NET logic uses App.Config files, reads information from connectionStrings sections, appSettings or needs any other data from configuration, you can use javOnet to load this file.

To do this, use the following method in your application. This method should be called just after activating javOnet and before any other operation. Simply add the BindConfig method to your application and call it by passing the path to your config file with config file name as an argument.

Example

public static void main(String[] args) throws JavonetException, IOException {  
  
  Javonet.activate("your@mail.com", "your-license-key", JavonetFramework.v40);  
  
  String path = new File( "." ).getCanonicalPath()+"\\"; 
  BindConfig(path+"app.config"); 
} 
 
private static void BindConfig(String configFile) throws JavonetException { 
  Javonet.getType("AppDomain") 
      .getRef("CurrentDomain") 
      .invoke("SetData","APP_CONFIG_FILE", configFile);  
}  

Debugging Javonet Enabled Application

Using Javonet both the JAVA and .NET code could be debugged and measured in very easy and convenient way. First you must understand the concept that Javonet loads the .NET process within the java process. Weather your application is hosted as standalone JAVA application, applet or web application both .NET and JAVA worlds will be combined either in javaw.exe, jUnit test runner process, Apache, jBoss or other host process.

Of course the JAVA part could be debugged with attached IDE debugger like Eclipse. To debug .NET code all you have to do is attach .NET debugger to your JAVA process. If you JAVA process lives very shortly you can set a break point just after the call to Javonet activate method and when your JAVA debugger hits that point then attach your .NET debugger. For example you can use Visual Studio environment by opening your .NET code project and choosing menu "Debug > Attach to process" and selecting the JAVA process to start debugging.

Using this approach both debuggers will allow you to go step by step through JAVA or .NET part of your code. The same solution might be applied for performance or memory measurements using any .NET and JAVA profiler of your choice.

This possibility gives you and your team very effective way of tracing the issues in your code and improves the quality of your solution.

XML Configuration File

There are many benefits to activating and setting up javOnet using an XML configuration file. It simplifies distribution of your application to your team, lets you update the javOnet license, references and framework configuration more quickly, and avoids hardcoded activation and configuration details.

During the first application use, javOnet searches for, and then automatically uses the XML configuration file to activate and configure your application.

Simply name the file “javonet.xml” and place it in the root directory of your JAVA application.

Below you can find the full structure of the XML configuration file. Some of the tags are optional. You can read more about Javonet XML configuration file in Activating Javonet and Adding references to .NET libraries sections.

Full Javonet XML Configuration File Structure

<?xml version="1.0" encoding="ISO-8859-1" ?>
<javonet>
<references> <!-- optional -->
    <reference>System.Windows.Forms</reference>
    <reference>System.Drawing</reference>
    <reference>yourDotNet.dll</reference>
</references>
<activation> <!-- mandatory -->
    <username>YOUR NAME</username>
    <email>your@email.com</email>
    <licencekey>YOUR-LICENSE-KEY</licencekey>
    <proxy> <!-- optional -->
         <host>your@email.com</host>
         <username>your@email.com</username>
         <password>your@email.com</password>
         <domain>your@email.com</domain>
    </proxy>
</activation>
<settings> <!-- optional (default .NET v35 and MTA) -->
    <apartmentState>STA</apartmentState> <!-- optional (default MTA) -->
    <framework>v40</framework> <!-- optional (default .NET v35) -->
</settings>
</javonet>
  • Łukasz Ładyński

    Cool!

Top