Instantiating Generic Collections

We had a question from a user recently asking how to instantiate certain generic collections in Java-to-.NET projects.  Some of the things that were discussed are of interest to the general community.

The user had a .NET method that was proxied to Java.  The method had several parameters, one of which was List<string>, and the other of which was Dictionary<string, List<string>>.  (Both List<> and Dictionary<,> were part of System.Collections.Generic.)  The questions were how to instantiate these collections and add elements to them.

This is actually one of the rare cases where you need to make use of the proxy for System.String. Ordinarily, .NET strings (System.String) are automatically converted to java.lang.Strings, and you never need to use the proxy for System.String, but you do here, since you need to access the .NET type object for System.String from the Java side.

To instantiate List<string>, you first need to make sure you’ve proxied System.String, as well as System.Collections.Generic.List__1 and System.Collections.Generic.Dictionary__2. Then use the code

import System.Collections.Generic.List__1;
import System.String;

List__1 theList = new List__1(String.GetDotNetClass());

Note that String above is the proxy of System.String, because of the import statement. We use that because we need the .NET typeof(string), not the Java String.class.

Note that the proxied List.Add() method has signature void Add(System.Object), so if we want to add a string using the proxied method, we need to do it as follows, using the DotNetString wrapper:

import System.DotNetString;

theList.Add(new DotNetString("a string"));

There are several ways to instantiate Dictionary<string, List<string>>, but they generally involve instantiating List<string> as above, and then getting a .NET Type object from that instantiated list. Sometimes you may need to instantiate such a list just to get the Type object; other times you may have such a list already lying around.  Here’s one way to do it, assuming you’ve instantiated theList as above.  If not, you can just write simple code to instantiate such a list and use that.

import System.Collections.Generic.Dictionary__2;

Dictionary__2 theDictionary = new Dictionary__2(String.GetDotNetClass(), theList.GetType());

Then, you can add key/value pairs to the dictionary as follows:

theDictionary.Add(new DotNetString("the key"), theList);

That’s really all there is to it. If you have any questions, or want to see some other examples, please don’t hesitate to contact us.

Serialization of proxies

Occasionally, customers ask how to serialize proxies, particularly .NET-side proxies, as part of the functionality of the application they’re developing. They’ve noticed that the proxies are not [Serializable]. We’ve spent a fair amount of time thinking about this, and there are some interesting issues in proxy serialization.

First, let’s consider reference proxies. A reference proxy contains a “remote reference” to the underlying Java object. The problem with making a reference proxy serializable is that, if the proxy could be serialized somehow, just the remote reference would be stored away. Now, assume that after the proxy was serialized, the Java side was shut down. Later, when the Java side is started up again, there’s no guarantee that the underlying Java object will be created; if the proxy is deserialized, there there’s no guarantee that the remote reference will point to anything useful, or even anything at all.

Value proxies, on the other hand, are snapshots of the underlying Java object, and are more self-contained than reference proxies. So, in theory, it should be possible to serialize a value proxy. Yes, but some of the members of the value proxy can themselves be reference proxies, and can have the same serialization/deserialization problems we’ve just described. We could arbitrarily decide that only the non-reference members of a value proxy will be serialized, and not attempt to serialize the reference members, but it’s not always clear to the user/developer which members are reference and which are value. It can get complicated and lead to unexpected user errors, and we strive to keep things simple for the users and provide features that don’t encourage errors.

So what do you do if you really want to serialize the proxies? All is not lost. .NET provides a little-known but really cool feature called a serialization surrogate. It’s a way to specify serialization behavior for classes that weren’t designed to be serializable. Once you’ve created and registered a serialization surrogate for a given class, then that class is henceforth treated as serializable (as defined by the surrogate). There’s a great article on serialization surrogates here.