note IKVMC0001: Found main method in class "Test"note IKVMC0002: Output file is "Test.exe"

C:\j>TestException in thread "main" java.lang.ExceptionInInitializerError at cli.System.Runtime.CompilerServices.RuntimeHelpers._RunClassConstructor(Unknown Source) at IKVM.Internal.TypeWrapper.RunClassInit(Unknown Source) at IKVM.NativeCode.java.lang.Class.forName0(Unknown Source) at java.lang.Class.forName(Class.java:287) at Test.main(Test.java:9)Caused by: cli.System.MethodAccessException: Test.m() at Other.<clinit>(Test.java)

The call from Other to Test fails with a MethodAccessException, because the dynamic assembly does not have access to the internal members of the Test.exe assembly.

Long ago I considered fixing this by adding an InternalsVisibleToAttribute to all statically compiled assemblies that allows the runtime generated dynamic assembly access to its internals, but I dismissed this because it would mean that untrusted code could abuse this same assembly identity to access the internals of any ikvmc compiled assemblies.

Forging a StrongNameKeyPair

Yesterday I realized that I could use InternalsVisibleToAttribute without opening a security hole. When the IKVM runtime is running as fully trusted code, it can forge a StrongNameKeyPair to attach to the dynamic assemblies it generates and thereby gain access to the statically compiled assemblies, without giving untrusted code the same access.

The only downside to this approach is that it relies on an implementation detail of the CLR (and Mono). I try to stay away from depending on implementation details, but in this case the gain far outways any risk.

Using It From C#

It also works for your C# assemblies. By adding a custom attribute, you can now enable dynamically loaded Java classes access to your assembly internals.

Here we create a Proxy for the non-public interface IFoo. This is allowed because of the InternalsVisibleToAttribute that gives access to an assembly named DemoApp-ikvm-runtime-injected with the specified public key. The name of the assembly must be the name of the current assembly (in this example "DemoApp") with "-ikvm-runtime-injected" appended. The public key is always the same. The corresponding private key does not exist.

Development Snapshot

Please note that this is a development snapshot, not a release or release candidate. So consider it untested.

Changes:

Use InternalsVisibleToAttribute to allow the runtime to dynamically inject classes into statically compiled assemblies.

I apologize for the lameness of this, but the comment spam was driving me nuts.
In order to be able to post a comment, you need to answer a simple question. Hopefully this question
is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the
one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)