From 084f3bf64e4e4ffb970c4e79e712693c961e124b Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Tue, 7 Jun 2022 17:34:35 +0700 Subject: [PATCH 1/5] Transfered most docs from https://sourceforge.net/p/ikvm/wiki. This is the initial state before converting examples to .NET Core. --- docs/class-loader.md | 127 +++++++++++++++++++++++ docs/class-not-found-exception.md | 41 ++++++++ docs/components.md | 36 +++++++ docs/concepts.md | 42 ++++++++ docs/convert-a-jar-file-to-a-dll.md | 106 +++++++++++++++++++ docs/create-a-property-in-java.md | 66 ++++++++++++ docs/cross-compiled-classes.md | 19 ++++ docs/debugging.md | 43 ++++++++ docs/installation.md | 36 +++++++ docs/run-a-jar-file-on-the-fly.md | 98 ++++++++++++++++++ docs/tools/ikvm.md | 73 +++++++++++++ docs/tools/ikvmc.md | 154 ++++++++++++++++++++++++++++ docs/tools/ikvmstub.md | 60 +++++++++++ docs/tools/index.md | 7 ++ docs/tutorial.md | 143 ++++++++++++++++++++++++++ docs/user-guide.md | 27 +++++ docs/using-dotnet-with-java.md | 49 +++++++++ docs/using-java-with-dotnet.md | 29 ++++++ 18 files changed, 1156 insertions(+) create mode 100644 docs/class-loader.md create mode 100644 docs/class-not-found-exception.md create mode 100644 docs/components.md create mode 100644 docs/concepts.md create mode 100644 docs/convert-a-jar-file-to-a-dll.md create mode 100644 docs/create-a-property-in-java.md create mode 100644 docs/cross-compiled-classes.md create mode 100644 docs/debugging.md create mode 100644 docs/installation.md create mode 100644 docs/run-a-jar-file-on-the-fly.md create mode 100644 docs/tools/ikvm.md create mode 100644 docs/tools/ikvmc.md create mode 100644 docs/tools/ikvmstub.md create mode 100644 docs/tools/index.md create mode 100644 docs/tutorial.md create mode 100644 docs/user-guide.md create mode 100644 docs/using-dotnet-with-java.md create mode 100644 docs/using-java-with-dotnet.md diff --git a/docs/class-loader.md b/docs/class-loader.md new file mode 100644 index 0000000000..e07c3daf44 --- /dev/null +++ b/docs/class-loader.md @@ -0,0 +1,127 @@ +# ClassLoader + +The class path or the usage of `ClassLoader`s is a little difficult because Java and .NET are not compatible. When there is an issue, it often results in a [ClassNotFoundException](class-not-found-exception.md). + +In Java you can set the class path with: + +- the environment variable CLASSPATH +- use the -cp switch on command line +- the property Class-Path in the MANIFEST.MF of a jar file. +- Use a `URLClassLoader` or your own `ClassLoader` + +This is a little different in .NET which can produce class loading problems. The following is a list of strategies that can be used to solve class loading problems on .NET. + +- [Compile time solutions](#compile-time-solutions) + - [One large assembly](#one-large-assembly) + - [AppDomainAssemblyClassLoader](#appdomainassemblyclassloader) + - [sharedclassloader](#sharedclassloader) + - [ClassPathAssemblyClassLoader](#classpathassemblyclassloader) +- [Runtime solutions](#runtime-solutions) + - [BootClassPathAssemby](#bootclasspathassembly) + - [Context class loader](#context-class-loader) + - [URLClassLoader](#urlclassloader) +- [Related blog entries](#related-blog-entries) + +## Compile time solutions + +### One large assembly + +The simplest solution is to compile all with [ikvmc](tools/ikvmc.md) in a single assembly. There is no class loading problem in this case. The disadvantages are: + +- a performance degree, you need to load all possible components. For example all supported JDBC driver if you only need one at one moment. +- duplicate resources files are lost. Like in one jar also in one dll a single file can exist only once. If the resources identical it is no problem. But with service for dynamic loading of components it is fatal. For example a JDBC driver registers it self if it in the classpath. If you have multiple JDBC drivers then only one is registers. + +### AppDomainAssemblyClassLoader + +This classloader loads from all assemblies that are currently loaded in your application (AppDomain in .NET lingo). So if a referenced assembly has not yet been loaded, it will not be searched at least not by the "AppDomain" part of the class loader, the default assembly class loader mechanism will still load referenced assemblies that are directly referenced by your assembly. + +You can set it with the follow command line: + +```console +ikvmc -classloader:ikvm.runtime.AppDomainAssemblyClassLoader MyJar.jar +``` + +### sharedclassloader + +If you compile multiple jar files to multiple assemblies then you can use the option sharedclassloader. + +```console +ikvmc -sharedclassloader { first.jar } { second.jar } { third.jar } +``` +You can only share the classloader between the jar files that was create in one step. + +### ClassPathAssemblyClassLoader + +It first searches the assembly (and, again, the assembly directly referenced) and then the class path. + +```console +ikvmc -classloader:ikvm.runtime.ClassPathAssemblyClassLoader MyJar.jar +``` + +## Runtime solutions + +### BootClassPathAssembly + +If you have a Visual Studio project then it does not help if you add the needed dlls as reference. You need also to use it. But an internal, dynamic use with Class.forName(x) can not detect as usage from Visual Studio. If you have a main program written in .NET then you can register your dll with the follow program line at startup of your program. + +```c# +ikvm.runtime.Startup.addBootClassPathAssembly(Assembly.Load("YourDll")); +``` +The class ikvm.runtime.Startup is saved in IKVM.OpenJDK.Core.dll. + +### Context class loader + +If you use one of the 3 class loaders for multiple DLL's then this has an effect to the default class loader. But Java know also the concept of the context class loader per thread. The standard class loader use the hierarchical class loader first and then the context class loader. + +There are some bad design Java library which only use the context class loader. This look like: + +```java +Class.forName( "org.company.abc.DynamicLoadedClass", true, Thread.currentThread().getContextClassLoader() ); +``` + +If you do not set the context class loader then it point to your main assembly and all assembly that are referenced from the compiler. Typical this means you can load all classes from your main assembly, the `BootClassPathAssembly` and from the first Java dll which you call directly. + +You can add references to all DLL's in your main assembly with lines like: + +```c# +GC.KeepAlive(typeof(org.company.abc.DynamicLoadedClass)); +``` + +This can be difficult if you have a large count of DLLs. Another solution is to set the context class loader to the same as the default class loader before you load the first class. + +```c# +java.lang.Class clazz = typeof(org.company.xyz.FirstClass); +java.lang.Thread.currentThread().setContextClassLoader( clazz.getClassLoader() ); +new org.company.xyz.FirstClass(); +``` + +### URLClassLoader + +Of course, you can also reuse existing class loader classes. Here's an example with `URLClassLoader`: + +```java +class MyCustomClassLoader extends java.net.URLClassLoader +{ + MyCustomClassLoader(cli.System.Reflection.Assembly asm) + { + super(new java.net.URL[0], new ikvm.runtime.AssemblyClassLoader(asm)); + // explicitly calling addURL() is safer than passing it to the super constructor, + // because this class loader instance may be used during the URL construction. + addURL(new java.net.URL("...")); + } +} +``` + +## Related blog entries + +- [Class Loading Architecture](https://web.archive.org/web/20210518052001/https://weblog.ikvm.net/PermaLink.aspx?guid=4e0b7f7c-6f5d-42a3-a4d6-5d05a99c84ff) +- [New Development Snapshot](https://web.archive.org/web/20080502034606/http://weblog.ikvm.net/PermaLink.aspx?guid=8a457a80-1e5f-4182-8f78-b2cd67845553) +- [Writing a Custom Assembly Class Loader](https://web.archive.org/web/20210518035313/http://weblog.ikvm.net/PermaLink.aspx?guid=375f1ff8-912a-4458-9120-f0a8cfb23b68) + +## Related + +- [ClassNotFoundException](class-not-found-exception.md) +- [Components](components.md) +- [Convert a .jar file to a .dll](convert-a-jar-file-to-a-dll.md) +- [ikvmc](tools/ikvmc.md) +- [Tutorial](tutorial.md) \ No newline at end of file diff --git a/docs/class-not-found-exception.md b/docs/class-not-found-exception.md new file mode 100644 index 0000000000..4a7352e607 --- /dev/null +++ b/docs/class-not-found-exception.md @@ -0,0 +1,41 @@ +# ClassNotFoundException + +One of the most ask question in the IKVM mailing list is the java.lang.ClassNotFoundException like: + +```java +Exception in thread "main" java.lang.ClassNotFoundException: com.xyz.Xyz + at java.net.URLClassLoader$1.run(URLClassLoader.java:366) + at java.net.URLClassLoader$1.run(URLClassLoader.java:355) + at java.security.AccessController.doPrivileged(AccessController.java:279) + at java.security.AccessController.doPrivileged(AccessController.java:520) + at java.net.URLClassLoader.findClass(URLClassLoader.java:354) + at java.lang.ClassLoader.loadClass(ClassLoader.java:450) + at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) + at java.lang.ClassLoader.loadClass(ClassLoader.java:385) + at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:500) + at IKVM.Internal.ClassLoaderWrapper.LoadClassImpl(Unknown Source) + at IKVM.Internal.ClassLoaderWrapper.LoadClassByDottedNameFastImpl(Unknown Source) + at IKVM.Internal.ClassLoaderWrapper.LoadClassByDottedName(Unknown Source) + at IKVM.NativeCode.java.lang.Class.forName0(Unknown Source) + at java.lang.Class.forName0(Native Method) + at java.lang.Class.forName(Class.java:287) +``` + +This occurs if you do a mistake at compile time. There can be the following causes: + +1. You forgot to compile a needed `.jar` file in an assembly. In this case you should have receive a IKVMC0105 error message from `ikvmc`. Add the missing `.jar` file to your `ikvmc` command line. +2. The different `.dll`s have no references to the other. A simple solution can be to use a [sharedclassloader](class-loader.md#sharedclassloader). +3. Analyze the `ikvmc` warnings to locate the name of the class which was not found. + +If this does not help then open a new issue on GitHub. Your issue should include: + +- The `ikvmc` command line(s). +- The name of the `.jar` file which include the missing class. +- The name of the `.jar` file which include the class which call `Class.forName`. This can you see in the line under `Class.forName`. +- The warnings from your `ikvmc` call. + +## Related + +- [ClassLoader](class-loader.md) +- [ikvmc Warnings](tools/ikvmc.md#warnings) +- [Tutorial](tutorial.md) \ No newline at end of file diff --git a/docs/components.md b/docs/components.md new file mode 100644 index 0000000000..48cb4ff558 --- /dev/null +++ b/docs/components.md @@ -0,0 +1,36 @@ +# Components of IKVM + +## Tools + +- [ikvm](tools/ikvm.md) + Starter executable, comparable to java.exe ("dynamic mode"). The Java application will start slow because all classes need to converted on the fly. + +- [ikvmc](tools/ikvmc.md) + Static compiler. Used to compile Java classes and jars into a .NET assembly ("static mode"). There are different classloader options. + +- [ikvmstub](tools/ikvmstub.md) + A tool that generates stub class files from a .NET assembly, so that Java code can be compiled against .NET code. IKVM understands the stubs and replaces the references to the stubs by references to the actual .NET types. + +- IKVM.Runtime.dll + The VM runtime and all supporting code. It contains (among other things): + + - Byte Code JIT compiler/verifier: Just-in-time compiles Java Byte Code to CIL. + - Object model remapping infrastructure: Makes System.Object, System.String and System.Exception appear to Java code as java.lang.Object, java.lang.String and java.lang.Throwable. + - Managed .NET re-implementations of the native methods in Classpath. + +- IKVM.Java.dll + This are a compiled version of the Java class libraries, plus some additional IKVM specific code. + +- ikvm-native.dll / libikvm-native.so +Small unmanaged C library that is used by the JNI interface. This is an optional part, and on Windows it is only required when an application uses it's own native libraries. When running on Linux, this library is also used by the NIO memory mapped files implementation. This library has been designed not to require any changes between IKVM versions, so if you download or compile a new version of IKVM, you don't necessarily need to update this native library. + +- IKVM.AWT.WinForms.dll + This are the AWT and Swing peers. This include the java.awt.Toolkit, fonts, images and more GUI stuff. + +## Related + +- [ClassLoader](class-loader.md) +- [ikvm](tools/ikvm.md) +- [ikvmc](tools/ikvmc.md) +- [ikvmstub](tools/ikvmstub.md) +- [User Guide](user-guide.md) \ No newline at end of file diff --git a/docs/concepts.md b/docs/concepts.md new file mode 100644 index 0000000000..60e6e61176 --- /dev/null +++ b/docs/concepts.md @@ -0,0 +1,42 @@ +# Concepts + +IKVM converts the Java byte-code into .NET IL code (Intermediate Language). This means the result is a .NET application. There are 2 modes for this conversion. On the fly with [ikvm](tools/ikvm.md) and via a compiler with [ikvmc](tools/ikvmc.md). + +In both mode you convert byte-code and not the API. IKVM is not a cross-compiler with exceptions. This means you need a Java runtime API in .NET. This are all the dll's of IKVM. This are approximate 40MB overhead for your application. Depending of the used API some not used dll's can be removed if you are finish. This is not recommend. + +There are also 2 types of code developments. You can write your code in any Java VM like Java or Scala. Or you write your code in any .NET language like C# or VB#. In the follow we will only speech from Java and C# also if any other language of this platform is possible. + +- [Running on the fly](#running-on-the-fly) +- [Running with compiler](#running-with-compiler) +- [Developing in Java code](#developing-in-java-code) +- [Developing in C# code](#developing-in-c-code) + +## Running on the fly + +In this case you need to develop in Java code (see below). You need only to replace the Oracle or OpenJDK runtime with the IKVM runtime. In some cases it can help to rename ikvm.exe to java.exe. This is how you should begin. This mode is most compatible to Java. + +The disadvantages is that this mode is very slow on start time. Every Java byte-code class need to converted to a IL class on every run. This is a large overhead for large projects. + +More details can you find in a completely [step by step example](run-a-jar-file-on-the-fly.md). + +## Running with compiler + +In this mode you compile one or more jar files to a dll or exe file. It is recommended to compile every jar file to a separate dll or exe file. This start many faster than the on the fly mode. + +The disadvantage is a switch from the Java class loading concept to the .NET class loading. Several strategies for dealing with the gap between .NET and Java are discussed in the [ClassLoader](class-loader.md) topic. + +## Developing in Java code + +To access .NET libraries in your Java code you create a stub file from a .NET library. This can you do with [ikvmstub](tools/ikvmstub.md). A IKVM stub file is a *.jar file, a Java library. It contains only definitions of classes and methods, but no code. If you run a stub file with the Oracle Java VM or OpenJDK you will receive an error. + +The .NET classes start with the package CLI. + +Some .NET constructs require a specific syntax in Java. This are list in [Using .NET with Java](using-dotnet-with-java.md). + +## Developing in C# code + +This is only possible with compiler mode. You compile you jar files to a dll or exe. Add it as reference to your IDE. You can use every class and method like from any other .NET class library. + +Some Java constructs require a specific syntax in .NET. This is exemplified in [Using Java with .NET](using-java-with-dotnet.md). + +See the [step by step example](convert-a-jar-file-to-a-dll.md) for details. \ No newline at end of file diff --git a/docs/convert-a-jar-file-to-a-dll.md b/docs/convert-a-jar-file-to-a-dll.md new file mode 100644 index 0000000000..0ec416fb91 --- /dev/null +++ b/docs/convert-a-jar-file-to-a-dll.md @@ -0,0 +1,106 @@ +# Convert a .jar file to a Class Library (.dll) + +This is the recommended solution if you want access a existing Java library from your .NET application. Depending on programming errors in the Java library this can be difficult. + +First you need to [download](https://github.com/ikvm-revived/ikvm/releases) and [install](installation.md) IKVM. + +## Java sample code + +First we create a hello world sample in Java and create a .jar file. The sample Java code of `HelloWorld.java` is very simple: + +```java +package hello; + +public class HelloWorld { + private String name; + + public HelloWorld() { + this.name = "World"; + } + + public HelloWorld(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Hello " + name; + } +} +``` + +You can save it as `HelloWorld.java` and compile it with the javac command line: + +```console +javac HelloWorld.java +``` + +This should create a file `HelloWorld.class`. With any zip program you can create a .jar file `HelloWorld.jar`. A jar file is only a zip file. The .jar file must include the file `HelloWorld.class` in the folder `hello`. This is the package name of the class. In Java package names are identical to folder names. + +## Create a dll + +The .jar file compile you with [ikvmc](tools/ikvmc.md). This can you do with the follow command line: + +```console +ikvmc -target:library HelloWorld.jar +``` + +If you want compile more as one .jar file then follow syntax is recommended: + +```console +ikvmc -target:library -sharedclassloader { first.jar } { second.jar } { third.jar } +``` + +Why this is recommend can you read in the [ClassLoader](class-loader.md) topic. This should produce the follow output: + +```console +IKVM.NET Compiler version x.x.xxxx.x +Copyright © 2022 Jeroen Frijters, Windward Studios, Jerome Haltom, Shad Storhaug + +note IKVMC0002: Output file is "HelloWorld.dll" +``` + +## C# Sample Code + +In your C# IDE you create a new project. Add a reference to `System` and `HelloWorld.dll`. Add a package reference on [IKVM](https://www.nuget.org/packages/IKVM). In your program file you can copy the follow C# sample code: + +```c# +using System; +using System.Reflection; + +namespace JavaLibrary +{ + class Program + { + static void Main(string[] args) + { + //Add references to all jar files that you use not directly + //ikvm.runtime.Startup.addBootClassPathAssemby(Assembly.Load("second")); + //ikvm.runtime.Startup.addBootClassPathAssemby(Assembly.Load("third")); + + // set a context classloader, this is not needed for the HelloWorld sample + // but solv problems with some buggy Java libraries + java.lang.Class clazz = typeof(hello.HelloWorld); + java.lang.Thread.currentThread().setContextClassLoader(clazz.getClassLoader()); + + object obj = new hello.HelloWorld(); + Console.WriteLine(obj); + obj = new hello.HelloWorld("Java"); + Console.WriteLine(obj); + } + } +} +``` + +If you run this program then it produce the follow output: + +```console +Hello World +Hello Java +``` + +## Related + +- [ClassLoader](class-loader.md) +- [ikvmc](tools/ikvmc.md) +- [Installation](installation.md) diff --git a/docs/create-a-property-in-java.md b/docs/create-a-property-in-java.md new file mode 100644 index 0000000000..3122978567 --- /dev/null +++ b/docs/create-a-property-in-java.md @@ -0,0 +1,66 @@ +# Create a Property in Java + +Java does not support the concept of properties as a code feature like C#. If you write a .NET library than it can be nice to have properties in your public API. + +## Properties via map.xml + + +At compile time you can use a `map.xml` file to modify the compiled result. The follow sample demonstrate the use of `map.xml` to define a property. + +```c# +public class IntList{ + private int[] list; + public IntList(int size){ + list = new int[size]; + } + public void setItem(int index, int value){ + list[index] = value; + } + public int getItem(int index){ + return list[index]; + } +} +``` + +### map.xml + +```xml + + + + + Item + + + + + + + + +``` + +When `IntList.java` is compiled to `IntList.class` and then IKVM compiled using: + +```console + ikvmc IntList.class -remap:map.xml +``` + +The resulting `IntList.dll` will be usable from C# like this: + +```c# + IntList l = new IntList(10); + l[4] = 42; + Console.WriteLine(l[4]); +``` + +Valdemar Mejstad created a tool to automatically generate the XML to define properties based on Java's java.beans.BeanInfo. The source is available here: [MapFileGenerator.java](https://web.archive.org/web/20161027171952/http://www.frijters.net/MapFileGenerator.java). + +## Properties via Annotation + +If you want create a property for a class member then you can use the annotation. + +```c# +@ikvm.lang.Property(get = "get_Handle") +private long Handle; +``` diff --git a/docs/cross-compiled-classes.md b/docs/cross-compiled-classes.md new file mode 100644 index 0000000000..6c1cdafb3e --- /dev/null +++ b/docs/cross-compiled-classes.md @@ -0,0 +1,19 @@ +# Cross-compiled Classes + +IKVM compiles the Java byte-code to .NET IL code. IKVM is not a cross-compiler but there are exceptions. Here is list of classes which will be cross-compiled. + +``` +java.lang.String +System.String +``` + +``` +lava.lang.Throwable +System.Exception +printStackTrace() shows the Java class name. +``` + +``` +java.lang.Class +System.Type +``` \ No newline at end of file diff --git a/docs/debugging.md b/docs/debugging.md new file mode 100644 index 0000000000..4beed4157d --- /dev/null +++ b/docs/debugging.md @@ -0,0 +1,43 @@ +# Debugging + +In some cases it is needed to debug a Java program that run with IKVM because there there are some things other us with the Sun Java VM. Currently IKVM does not have a Java debug interface. If you want contribute your help is very welcome. + +## Run in Eclipse + +You can not debug a IKVM application but you can run it with Eclipse. Then you can add debug output to your program with System.out. If you want run a Java application with Eclipse then you need: + +- Copy ikvm.exe to java.exe. If you update your IKVM then you should repeat this. +- Create a lib directory parallel to the bin directory. +- Copy a rt.jar from an existing Sun Java VM in the lib directory. +- In the Eclipse "Preference | Java | Installed JREs" add a standard VM. This should be possible now. If not then you need to restart Eclipse. Eclipse check one directory only once. + + +Change the launch of you your program that it use the IKVM. It can be helpful to copy the launch and use one for the Sun VM and one for IKVM. + +## Debugging with Visual Studio + +Because IKVM is a .NET application that it is possible to debug it with Visual Studio or Visual Studio Express for C#. + +- First you must checkout IKVM from GitHub. +- Then you must build it or copy a compiled version in the bin directory +- In the file source file vfs.cs you need to replace the line: + + ```c# + return Assembly.GetExecutingAssembly().GetManifestResourceStream("vfs.zip"); + ``` + + with: + + ```c# + return new System.IO.FileStream("c:\\ikvm\\openjdk\\vfs.zip", System.IO.FileMode.Open); + ``` + +- Change the path to your `vfs.zip` + +An alternative solution is to add `vfs.zip` to the project IKVM.Runtime and set the build property to embedded. Because Visual Studio copy the file in the project root that you need to copy from time to time a new version of vfs.zip in the project root. + +If you want debug inside the original Java sources then you need to compile it with debug. This can you do in the build file `response.txt`. Add the flag `-debug` to the block of every dll that you want debug. + +## Related + +- [Installation](installation.md) \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000000..74bfae5968 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,36 @@ +# Installation + +The installation procedure for both Windows and Linux is straightforward. After downloading the binary distribution, simply extract the files from the archive. Open a command or shell window, cd to `ikvm\bin`, and type: + +```console +ikvm +``` + +If your system is operating correctly, you should see the following output: + +```console +usage: ikvm [-options] <class> [args...] + (to execute a class) + or ikvm -jar [-options] <jarfile> [args...] + (to execute a jar file) ... +``` + +For convenience, you may wish to add the `\ikvm\bin` folder to your system's path, but this is not required. Now, if all you want to do is use IKVM as a Java VM, you're done -- no further configuration is needed. If you want to use IKVM for .NET / Mono development, read the configuration instructions below. + +## Configuration for Development + +If you plan to do .NET development with IKVM, you may wish to do the following: + +- Download a Java SDK + If you plan to develop code in Java that runs in .NET, you will need a Java compiler. IKVM does not come with a compiler. You may use any Java compiler that emits standard Java .class files. The [Debugging] is a little difficult but possible. Because not every Java syntax can 100% mirror to .NET here is a syntax help for [Using_Java_with_.NET]. + +- Windows: Install IKVM dll's in the Global Assembly Cache + When running .NET applications in Windows that use IKVM dll's, the .NET framework must be able to locate the dll's. It looks in the Global Assembly Cache, then in the current directory. If you want to be able to do development without having the dll's in the current directory, you must install them in the Global Assembly Cache. To do this in Windows, access the Microsoft .NET Framework Configuration item in the Windows Control Panel, and add the assemblies to the Assembly Cache. At a minimum, you will want to install the IKVM.OpenJDK.*.dll and IKVM.Runtime.dll. + +## Related + +- [Convert a .jar file to a .dll](convert-a-jar-file-to-a-dll.md) +- [Debugging](debugging.md) +- [Download](https://github.com/ikvm-revived/ikvm/releases) +- [Run a .jar file on the fly](run-a-jar-file-on-the-fly.md) +- [Using Java with .NET](using-java-with-dotnet.md) diff --git a/docs/run-a-jar-file-on-the-fly.md b/docs/run-a-jar-file-on-the-fly.md new file mode 100644 index 0000000000..a4d9428480 --- /dev/null +++ b/docs/run-a-jar-file-on-the-fly.md @@ -0,0 +1,98 @@ +# Run a .jar file on-the-fly + +With IKVM you can run dynamically one or multiple `.jar` files on the fly in a .NET application. This is only a solution for small .jar files or for a server because the startup time is slow. The `.jar` file need to compile on the fly to IL code. You can also call the code only via reflection. + +First you need to download and install IKVM. + +## Java sample code + +First we create a hello world sample in Java and create a jar file. The sample Java code of `HelloWorld.java` is very simple: + +```java +package hello; + +public class HelloWorld { + private String name; + + public HelloWorld() { + this.name = "World"; + } + + public HelloWorld(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Hello " + name; + } +} +``` + +You can save it as HelloWorld.java and compile it with the javac command line: + +```console +javac HelloWorld.java +``` + +This should create a file HelloWorld.class. With any zip program you can create a jar file `HelloWorld.jar`. A .jar file is only a zip file. The .jar file must include the file `HelloWorld.class` in the folder `hello`. This is the package name of the class. In Java package name are identical to folder names. + +## C# Sample code + +In your C# IDE you create a new project. Add a reference to `System` and package reference on [IKVM](https://www.nuget.org/packages/IKVM). Copy the `HelloWorld.jar` file in the project root and set "Copy always". In your program file you can copy the follow C# sample code: + +```c# +using System; + +namespace DynamicLoading +{ + class Program + { + static void Main(string[] args) + { + // Create a URL instance for every jar file that you need + java.net.URL url = new java.net.URL("file:HelloWorld.jar"); + // Create an array of all URLS + java.net.URL[] urls = { url }; + // Create a ClassLoader + java.net.URLClassLoader loader = new java.net.URLClassLoader(urls); + try + { + // load the Class + java.lang.Class cl = java.lang.Class.forName("hello.HelloWorld", true, loader); + + // Create a Object via Java reflection + object obj = cl.newInstance(); + Console.WriteLine(obj); + obj = cl.getConstructor(typeof(string)).newInstance("Java"); + Console.WriteLine(obj); + + //Create a object via C# reflection + Type type = ikvm.runtime.Util.getInstanceTypeFromClass(cl); + obj = type.GetConstructor(new Type[]{}).Invoke(null); + Console.WriteLine(obj); + obj = type.GetConstructor(new Type[] { typeof(string)}).Invoke( new object[]{"C#"}); + Console.WriteLine(obj); + } + catch (Exception ex) + { + Console.WriteLine(ex); + Console.WriteLine(ex.StackTrace); + } + } + } +} +``` + +If you run this program then it produce the follow output: + +```console +Hello World +Hello Java +Hello World +Hello C# +``` + +## Related + +- [Installation](#installation.md) diff --git a/docs/tools/ikvm.md b/docs/tools/ikvm.md new file mode 100644 index 0000000000..0928b65f4b --- /dev/null +++ b/docs/tools/ikvm.md @@ -0,0 +1,73 @@ +# ikvm Tool + +The ikvm tool is a Java virtual machine implemented in .NET. + +## Usage + +```console +ikvm [ options ] [ args ... ] +ikvm [ options ] -jar [ args ... ] +``` + +options + +Command-line options for the virtual machine. + +classname + +Fully-qualified name of a class containing the main method to execute. Do not include a path or a `.class` extension. Do not use this with the `-jar` option. + +jarfile + +The name of an executable `.jar` file to execute. Used only with the `-jar` option. + +args + +Command-line arguments passed to the main class. + + +## Options + +| Source | Description | +|---|---| +| `-?\|-help` | Displays command syntax and options for the tool. | +| `-version` | Displays IKVM and runtime version. | +| `-showversion` | Display version and continue running. | +| `-cp\|-classpath` | <directories and zip/jar files separated by ;> Set search path for application classes and resources. | +| `-D=` | Set a Java system property. | +| `-ea\|-enableassertions[: [...] \|:]` | Set Java system property to enable assertions. | +| `-da\|-disableassertions[: [...] \|:]` | Set Java system property to disable assertions. | +| `-Xsave` | Save the generated assembly (for debugging). | +| `-Xtime` | Time the execution. | +| `-Xtrace:` | Displays all trace points with the given name. | +| `-Xmethodtrace:` | Builds method trace into the specified output methods. | +| `-Xwait` | Keep process hanging around after exit. | +| `-Xbreak` | Trigger a user defined breakpoint at startup. | +| `-Xnoclassgc` | Disable class garbage collection. | +| `-Xnoglobbing` | Disable argument globbing. | +| `-Xverify` | Enable strict class file verification. | +| `-Xreference:/.dll` | Add a assembly (dll or exe) as reference to the classpath. This equals the C# code `Startup.addBootClassPathAssemby(Assembly.LoadFrom(name));`. | +| `-jar` | Run a jar file. | +| `-Xdebug` | Enable debugging. | +| `-Xnoagent` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-XX:+AllowNonVirtualCalls` | Allow non-virtual calls. | +| `-XX:` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xms` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xmx` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xss` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xmixed` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xint` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xincgc` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xbatch` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xfuture` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xrs` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xcheck:jni` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xshare:off` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xshare:auto` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xshare:on` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | + +## Related + +- [Components](../components.md) +- [Tools](index.md) +- [Tutorial](../tutorial.md) \ No newline at end of file diff --git a/docs/tools/ikvmc.md b/docs/tools/ikvmc.md new file mode 100644 index 0000000000..4107d2a563 --- /dev/null +++ b/docs/tools/ikvmc.md @@ -0,0 +1,154 @@ +# ikvmc Tool + +The `ikvmc` tool converts Java bytecode to .NET dll's and exe's. + +- [Usage](#usage) +- [Options](#options) +- [Notes](#notes) +- [Examples](#examples) + - [Single jar file](#single-jar-file) + - [jar file and class files to a single exe](#jar-file-and-class-files-to-a-single-exe) + - [jar file to dll and class files to an exe](#jar-file-to-dll-and-class-files-to-an-exe) +- [Warnings](#warnings) + +## Usage + +```console +ikvmc [ options ] [ classOrJarfile... ] +``` + +options + +See below. + +classOrJarfile + +Name of a Java `.class` or `.jar file`. May contain wildcards (`*.class`). + +## Options + +| Source | Description | +|---|---| +| `-?\|-help` | Displays command syntax and options for the tool. | +| `@` | Read more options from the provided file. | +| `-out:` | Specifies the name of the `outputfile`. Should have a .dll extension (if -target is library) or an .exe extension (if -target is exe or winexe). In most cases, if you omit this option, `ikvmc` will choose an output name based on the -target and the name of the input files. However, if you specify input files using wildcards, you must use this option to specify the output file. | +| `-assembly:` | Specifies the name of the generated assembly. If omitted, the assembly name is (usually) the output filename. | +| `-target:` | Specifies whether to generate an .exe or .dll. `target-type` is one of
  • `exe` - generates an executable that runs in a Windows command window
  • `winexe` - generates an .exe for GUI applications
  • `library` - generates a .dll
  • `module` - generates a .netmodule
On Linux, there is no difference between exe and winexe. | +| `-platform:` | Limit which platforms this code can run on:
  • `x86` - 32 bit
  • `Itanium`
  • `x64`
  • `anycpu`
The default is `anycpu`. This can be helpful if your Java code use a dll via JNI. For example a 32 bit dll should also run on a 64 bit system as 32 bit application. | +| `-keyfile:` | Uses `keyfilename` to sign the resulting assembly. | +| `-key` | Use `keycontainer` to sign the assembly. | +| `-delaysign` | Delay-sign the assembly. | +| `-version:` | Specifies the output assembly version. | +| `-fileversion:` | Specifies the output assembly file version. | +| `-main:` | Specifies the name of the class containing the main method. If omitted and the -target is exe or winexe, ikvmc searches for a qualifying main method and reports if it finds one. | +| `-r:\|-reference:` | If your Java code uses .NET API's, specify the dll's using this option. This option can appear more than once if more than one library is referenced. Wildcards are permitted (e.g. `C:\libs\*.dll`). | +| `-recurse:` | Processes all files matching `filespec` in and under the directory specified by filespec. Example: `-recurse:*.class` | +| `-nojni` | Do not generate JNI stub for native methods. | +| `-resource:=` | Includes path as a Java resource named `name`. | +| `-externalresource:=` | Reference file as Java resource. | +| `-win32icon:` | Embed specified icon in output. | +| `-win32manifest:` | Specify a Win32 manifest file (.xml). | +| `-compressresources` | Compress resources. | +| `-exclude:` | `filename` is a file containing a list of classes to exclude. | +| `-debug` | Generates debugging information in the output. Note that this is only helpful if the `.class` files contain debug information (compiled with the `javac -g` option). | +| `-srcpath:` | Specifies the location of source code. Use with `-debug`. The package of the class is appended to the specified `path` to locate the source code for the class. | +| `-Xtrace:` | Displays all trace points with `name`. | +| `-Xmethodtrace:` | Builds method trace into the specified output method. | +| `-noautoserialization` | Disable automatic .NET serialization support. | +| `-noglobbing` | Don't glob the arguments passed to `-main`. | +| `-nojni` | Do not generate JNI stub for native methods. | +| `-opt:fields` | Remove unused private fields. | +| `-removeassertions` | Remove all assert statements. | +| `-strictfinalfieldsemantics` | Don't allow final fields to be modified outside of initializer methods. | +| `-nowarn:` | Suppress specified warnings. | +| `-warnaserror` | Treat all warnings as errors. | +| `-warnaserror:` | Treat specified warnings as errors. | +| `-writeSuppressWarningsFile:` | Write response file with `-nowarn:` options to suppress all encountered warnings. | +| `-nologo` | Suppress compiler copyright message. | +| `-srcpath:` | Prepend path and package name to source file. | +| `-apartment:` | Apply a thread apartment state attribute to `-main` based on the selected option:
  • `sta` - Apply `STAThreadAttribute`
  • `mta` - Apply `MTAThreadAttribute`
  • `none` - Apply no attribute
The default option is `sta`. | +| `-D=` | Set a Java system property (at runtime). | +| `-ea\|-enableassertions[: [...] \|:]` | Set Java system property to enable assertions. | +| `-da\|-disableassertions[: [...] \|:]` | Set Java system property to disable assertions. | +| `-nostacktraceinfo` | Don't create metadata to emit rich stack traces. | +| `-privatepackage:` | Mark all classes with a package name starting with `prefix` as internal to the assembly. | +| `-publicpackage:` | Mark all classes with a package name starting with `prefix` as public to the assembly. | +| `-time` | Display timing statistics. | +| `-classloader:` | Set custom class loader class for assembly. | +| `-sharedclassloader` | All targets below this level share a common class loader. | +| `-baseaddress:
` | Base address for the library to be built. | +| `-filealign:` | Specify the alignment used for output file. | +| `-nopeercrossreference` | Do not automatically cross reference all peers. | +| `-nostdlib` | Do not reference shared reference assemblies. | +| `-lib:` | Additional directories to search for references. This option may be specified more than once. | +| `-highentropyva` | Enable high entropy ASLR. | +| `-static` | Disable dynamic binding. | +| `-assemblyattributes:` | Read assembly custom attributes from specified class file. | +| `-proxy:` | Undocumented. | +| `-nojarstubs` | Undocumented temporary option to mitigate risk. | +| `-w4` | Undocumented option to compile core class libraries with, to disable MethodParameter attribute. | +| `-strictfinalfieldsemantics` | Undocumented. | +| `-remap` | Undocumented. | + +## Notes + +The ikvmc tool generates .NET assemblies from Java class files and jar files. It converts the Java bytecode in the input files to .NET CIL. Use it to produce + +- .NET executables (`-target:exe` or `-target:winexe`) +- .NET libraries (`-target:library`) +- .NET modules (`-target:module`) + +Java applications often consist of a collection of `.jar` files. `ikvmc` can process several input `.jar` files (and class files) and produce a single .NET executable or library. For example, an application consisting of `main.jar`, `lib1.jar`, and `lib2.jar` can be converted to a single `main.exe`. + +When processing multiple input `.jar` files that contain duplicate classes / resources, `ikvmc` will use the first class / resource it encounters, and ignore duplicates encountered in `.jar`s that appear later on the command line. It will produce a warning in this case. Thus, the order of `.jar` files can be significant. + +#### Note + +- When converting a Java application with `ikvmc`, for best results, list the `.jar`s on the `ikvmc` command line in the same order that they appear in the Java application's classpath. + See also the concepts of [ClassLoader](../class-loader.md). +- [ikvmc messages](ikvmc-messages.md) + + +## Examples + +### Single jar file + +```console +ikvmc myProg.jar +``` + +Scans `myprog.jar` for a `main()` method. If found, an `.exe` is produced; otherwise, a `.dll` is generated. + +### jar file and class files to a single exe + +```console +ikvmc -out:myapp.exe -main:org.anywhere.Main -recurse:bin\*.class lib\mylib.jar +``` + +Processes all `.class` files in and under the bin directory, and `mylib.jar` in the lib directory. Generates an executable named `myapp.exe` using the class `org.anywhere.Main` as the `main()` method. + +### jar file to dll and class files to an exe + +```console +ikvmc mylib.jar +ikvmc -out:myapp.exe -main:org.anywhere.Main -recurse:bin\*.class -reference:mylib.dll +``` + +First it generates a library `mylib.dll` from `mylib.jar`. Then it generates an executable named `myapp.exe` from all `.class` files in and under the bin directory using the class `org.anywhere.Main` as the main method. This make duplicate file names possible which are used from the Java service API. + +## Warnings + + +| Warning Number | Message | Cause | +|---|---|---| +| IKVMC0100 | class "com.company.mypackage.Xyz" not found (in mylibrary.dll) | This can be a follow error of IKVMC0105. | +| IKVMC0105 | unable to compile class "com.company.mypackage.Xyz" (missing class "com.company.mypackage.Abc") | The class com.company.mypackage.Abc was not found. If this is an optional external class then you can ignore it. | +| IKVMC0109 | skipping class: "javax.activation.ActivationDataFlavor" (class is already available in referenced assembly "IKVM.OpenJDK.Beans ...) | This class was only needed for older Java versions. In the current version it is already included.
  • You have the class added more as once to the compiler
  • You can ignore it if you does not have a special version.
| + +## Related + +- [ClassLoader](../class-loader.md) +- [Components](../components.md) +- [Convert a .jar file to a .dll](../convert-a-jar-file-to-a-dll.md) +- [Tools](index.md) +- [Tutorial](../tutorial.md) \ No newline at end of file diff --git a/docs/tools/ikvmstub.md b/docs/tools/ikvmstub.md new file mode 100644 index 0000000000..be84188c37 --- /dev/null +++ b/docs/tools/ikvmstub.md @@ -0,0 +1,60 @@ +# ikvmstub Tool + +The `ikvmstub` tool generates Java stubs from .NET assemblies. + +## Usage + +```console +ikvmstub [options] +``` + +assemblyNameOrPath + +Name of an assembly. May be a fully-qualified path. + +## Options + +| Source | Description | +|---|---| +| No `` provided | Displays command syntax and options for the tool. | +| `-out:` | Specifies the name of the `outputfile`. | +| `-r:\|-reference:` | Reference an assembly. | +| `-japi` | Generate `.jar` suitable for comparison with japitools. | +| `-skiperror` | Continue when errors are encountered. | +| `-shared` | Process all assemblies in shared group. | +| `-nostdlib` | Do not reference shared reference assemblies. | +| `-lib:` | Additional directories to search for references. This option may be specified more than once. | +| `-namespace:` | Only include types from specified `namespace`. This option may be specified more than once. | +| `-forwarders` | Export forwarded types too. | +| `-parameters` | Emit Java 8 classes with parameter names. | + + +## Notes + +`ikvmstub` reads the specified assembly and generates a Java `.jar` file containing Java interfaces and stub classes. For more information about the generated stubs, see the [Tutorial](../tutorial.md). + +The tool uses the following algorithm to locate the assembly: + +1. First it attempts to load the assembly from the default load context of `ikvmstub`. For practical purposes, this usually means it searches the Global Assembly Cache. +2. If not found in the default load context, `ikvmstub` looks for the assembly at the indicated path (or the current directory, if no path is supplied). + + +## Examples + +```console +ikvmstub mscorlib.dll +``` + +Generates `mscorlib.jar`, containing stubs for classes, interfaces, etc., defined in `mscorlib.dll`. + +```console +ikvmstub c:\lib\mylib.dll +``` + +Generates `mylib.jar`, containing stubs for classes, interfaces, etc., defined in `c:\lib\mylib.dll`. + +## Related + +- [Components](../components.md) +- [Tools](index.md) +- [Tutorial](../tutorial.md) \ No newline at end of file diff --git a/docs/tools/index.md b/docs/tools/index.md new file mode 100644 index 0000000000..4f9d46fc66 --- /dev/null +++ b/docs/tools/index.md @@ -0,0 +1,7 @@ +# Tools + +IKVM includes the following tools: + +- [ikvm](ikvm.md) - Java Virtual Machine +- [ikvmc](ikvmc.md) - Compiles Java Bytecode to CIL +- [ikvmstub](ikvmstub.md) - Generates Java stub classes from .NET assemblies \ No newline at end of file diff --git a/docs/tutorial.md b/docs/tutorial.md new file mode 100644 index 0000000000..e035aa8521 --- /dev/null +++ b/docs/tutorial.md @@ -0,0 +1,143 @@ +# IKVM Tutorial + +- [Setup your Environment](#setup-your-environment) +- [Run a Java Application Dynamically](#run-a-java-application-dynamically) +- [Convert a Java Application to .NET](#convert-a-java-application-to-net) +- [Develop a .NET Application in Java](#develop-a-net-application-in-java) + - [Step 1: Generate Java stubs](#step-1-generate-java-stubs) + - [Step 2: Compile the Java source code](#step-2-compile-the-java-source-code) + - [Step 3: Generate a .NET executable](#step-3-generate-a-net-executable) + +## Setup your Environment + +This tutorial includes information for both the Windows and Linux platforms. It assumes that Windows users will be using the .NET SDK, and Linux users will be using the Mono SDK. + +This tutorial references files in the samples distribution available on the [Releases](https://github.com/ikvm-revived/ikvm/releases) page. Before you begin, prepare your environment by adding the following to your PATH environment variable: + +- The directory containing the IKVM executables +- The directory containing the C# compiler (Windows: csc / Mono: mcs). On Windows, this is typically C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322. +- The directory containing a Java compiler (javac or jikes) + + +## Run a Java Application Dynamically + +IKVM includes a Java Virtual Machine implemented in C#. To try it out, navigate to `IKVMROOT\samples\hello` and compile the sample application: + +```console +javac Hello jar cfm hello.jar manifest.mf Hello.class +``` + +Now, to run the application using the IKVM Virtual Machine, enter the following: + +```console +ikvm Hello +``` + +This command starts the virtual machine, which searches for a file named `Hello.class`. When it finds it, it loads it and executes the bytecode dynamically. You should be prompted to enter your name, and see a brief greeting. + +If you experience problems, check the following: + +- Check your capitalization: ikvm, like java, requires you to capitalize class names correctly. +- If ikvm reports a [ClassNotFoundException](class-not-found-exception.md), check whether the `CLASSPATH `environment variable is set. If so, try clearing the `CLASSPATH` or adding the current directory to it so ikvm can find the class in the current directory. + +You can also execute Java applications in a jar file. Try it out: + +```console +ikvm -jar hello.jar +``` + +See the [ikvm](tools/ikvm.md) reference for more information about `ikvm` command line options. + +## Convert a Java Application to .NET + +IKVM includes [ikvmc](tools/ikvmc.md), a utility that converts Java `.jar` files to .NET .dll libraries and .exe applications. In this section, you'll convert a Java application to a .NET .exe. + +Navigate to `IKVMROOT\samples\hello` and enter the following: + +```console +ikvmc hello.jar +``` + +After the command completes, you should find a `hello.exe` file in the current directory. To execute it: + +### Windows / .NET Framework: +- Try running `hello.exe`. If you get a `FileNotFoundException` when the .NET runtime attempts to load the referenced `IKVM.Java.dll`, remember that the .NET Framework expects to find referenced dll's in the application directory or in the Global Assembly Cache. Either install the dll's in the Global Assembly Cache, or copy them to the application directory. + +### Linux / Mono: + +Run it using the following command: + +```console +mono hello.exe +``` + +## Develop a .NET Application in Java + +In this section, you will learn the steps needed to develop .NET applications in Java. Take a look at the source code of `ShowDir.java` -- this is a Java application that uses the .NET API to display a list of files in the current directory. + +```java +import cli.System.IO.*; + +public class ShowDir{ + + public static void main(String[] args){ + String[] files = Directory.GetFiles("."); + for(String file : files){ + System.out.println(file); + } + } +} +``` + +Notice the imports at the top -- the package names begin with cli.*. These are not packages in the Java API; rather, they are "pseudo" packages that map to .NET namespaces. + +### Step 1: Generate Java stubs + +IKVM does not come with a Java compiler, so we will compile ShowDir using a standard Java compiler. Since Java compilers can only compile applications that use Java API's, not .NET API's, we have to fool the Java compiler into believing that there is really a Java package named `cli.System.IO`. The [ikvmstub](tools/ikvmstub.md) application helps us do this. It generates Java `.jar` files from .NET dll's. The `.jar` files generated by [ikvmstub](tools/ikvmstub.md) contain Java classes and interfaces that correspond to .NET classes, but don't contain any real code. They contain just enough to satisfy the Java compiler, and allow it to type check the Java application. + +Type the following: + +```console +ikvmstub mscorlib.dll +``` + +Note: On a Linux Mono installation, you will have to type the full pathname to `mscorlib.dll`, like this: + +```console +ikvmstub /usr/lib/mscorlib.dll +``` + +After the command completes, you should find a file named `mscorlib.jar` in the current directory. + +### Step 2: Compile the Java source code + +Now, we'll compile the Java source code. If you're using `javac`, type the following: + +```console +javac -classpath mscorlib.jar ShowDir.java +``` + +(Substitute jikes for javac if you're using that tool.) Of course you can also use any Java IDE like Eclipse. + +After the command completes, you should find `ShowDir.class` in the current directory. + +### Step 3: Generate a .NET executable + +Now, we'll convert the Java class file to a .NET application. Type the following: + +```console +ikvmc -r:mscorlib.dll ShowDir.class +``` + +After the command completes, you should find `ShowDir.exe` in the current directory. You should be able to execute it successfully. (On Windows .NET, remember to copy the IKVM dll's to the current directory.) + +See for [ikvmc](tools/ikvmc.md) and [ClassLoader](class-loader.md) for more details. + +## Related + +- [ClassLoader](class-loader.md) +- [ClassNotFoundException](class-not-found-exception.md) +- [Download](https://github.com/ikvm-revived/ikvm/releases) +- [ikvm](tools/ikvm.md) +- [ikvmc](tools/ikvmc.md) +- [ikvmstub](tools/ikvmstub.md) diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000000..90f62017c1 --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,27 @@ +# User Guide + +IKVM is a Java Virtual Machine (JVM) for the .NET and Mono runtimes. At a time when most people in the computer industry consider Java and .NET as mutually exclusive technologies, IKVM stands in the unique position of bringing them together. Initially born out of frustration with the limitations of tools like JUMP and J#, IKVM was created when Jeroen Frijters set out to create a way to migrate an existing Java database application to .NET. + +IKVM has gone through a variety of designs and name changes to emerge as a sophisticated collection of tools offering a variety of integration patterns between the Java and .NET languages and platforms. It is still under development but people have reported success in running sophisticated applications and tools including Eclipse, JmDNS, JGroups, Jetty (with a few changes), etc. + +## Overview + +There are two main ways of using IKVM: + +- Dynamically: In this mode, Java classes and jars are used directly to execute Java applications on the .NET runtime. Java bytecode is translated on the fly into CIL and no further steps are necessary. The full Java class loader model is supported in this mode. +- Statically: In order to allow Java code to be used by .NET applications, it must be compiled down to a DLL and used directly. The bytecode is translated to CIL and stored in this form. The assemblies can be referenced directly by the .NET applications and the "Java" objects can be used as if they were .NET objects. While the static mode does not support the full Java class loader mechanism, it is possible for statically-compiled code to create a class loader and load classes dynamically. + +IKVM provides the VM-related technologies for byte-code translation and verification, classloading, etc. It is dependent upon the OpenJDK project for implementations of the JDK libraries. + +IKVM is comprised by the different [Components](components.md). + +## System Requirements + +You must have one of the following .NET frameworks installed: + +Microsoft .NET Framework 2.0 SP1 (or later) Framework (Windows platform) +Mono 2.0 (or later) (Windows or Linux) + +## Related + +- [Components](components.md) diff --git a/docs/using-dotnet-with-java.md b/docs/using-dotnet-with-java.md new file mode 100644 index 0000000000..ae120caad6 --- /dev/null +++ b/docs/using-dotnet-with-java.md @@ -0,0 +1,49 @@ +# Using .NET With Java + +```c# +typeof operator +System.Type type = typeof(com.mypack.MyClass); +cli.System.Type type = ikvm.runtime.Util.getInstanceTypeFromClass(com.mypack.MyClass.class); + +enum value +MyEnum.Value1 +MyEnum.wrap( MyEnum.Value1 ) + +bool +bool a = true; + +if ( a ) { + +cli.System.Boolean a = kvm.lang.CIL.box_boolean(true); // add ikvm-api.jar to your classpath + +if ( kvm.lang.CIL.unbox_boolean( a ) { + +// property +obj.PropertyName +obj.get_PropertyName() + +// events +obj.SomeChange += new MySomeChange( AnyMethod ); + + obj.add_SomeChange( + new cli.System.EventHandler ( + new cli.System.EventHandler.Method () { + public void Invoke (Object sender, cli.System.EventArgs e) { + ... + } + } + ) + ); + +// annotation +[System.ThreadStaticAttribute] +@cli.System.ThreadStaticAttribute.Annotation +``` + +## Attributes as Annotations + +With some limitations you can use .NET attributes as explained in Attribute Annotations post. + +## Related + +- [Using Java with .NET](using-java-with-dotnet.md) \ No newline at end of file diff --git a/docs/using-java-with-dotnet.md b/docs/using-java-with-dotnet.md new file mode 100644 index 0000000000..0523ad997e --- /dev/null +++ b/docs/using-java-with-dotnet.md @@ -0,0 +1,29 @@ +# Using Java with .NET + +Most Java classes can be accessed directly. There is no package prefix. The article [C# from a Java Developer's Perspective](http://www.25hoursaday.com/CsharpVsJava.html) can be helpful. + +Some Java syntax is not compatible and requires some hacks and has some specific notation. + +```c# +class operator +Class clazz = com.mypack.MyClass.class; +Class clazz = typeof(com.mypack.MyClass); + +// enum + +MyEnum value; +switch(value){ + case VALUE1: + ... + +MyEnum value; +switch(value.ordinal()){ + case (int)MyEnum.__Enum.VALUE1: + ... +``` + +## Related + +- [Installation](installation.md) +- [Using .NET with Java](using-dotnet-with-java.md) + From bbc4a750ca2e6a16aecd6c348c5744628e661b18 Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Mon, 11 Jul 2022 00:32:22 +0700 Subject: [PATCH 2/5] docs/tools/ikvm.md: Grouped options in a similar way as the java.exe documentation. --- docs/tools/ikvm.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/tools/ikvm.md b/docs/tools/ikvm.md index 0928b65f4b..24aa7df1c7 100644 --- a/docs/tools/ikvm.md +++ b/docs/tools/ikvm.md @@ -28,16 +28,28 @@ Command-line arguments passed to the main class. ## Options -| Source | Description | +### Standard Options + +|                           Source                           |                                                              Description                                                               | |---|---| | `-?\|-help` | Displays command syntax and options for the tool. | | `-version` | Displays IKVM and runtime version. | | `-showversion` | Display version and continue running. | | `-cp\|-classpath` | <directories and zip/jar files separated by ;> Set search path for application classes and resources. | +| `-jar` | Run a jar file. | +| `-D=` | Set a Java system property. | +| `-ea\|-enableassertions[:[\|]]` | Set Java system property to enable assertions. A class name or package name can be specified to enable assertions for a specific class or package. | +| `-da\|-disableassertions[:[\|]]` | Set Java system property to disable assertions. A class name or package name can be specified to disable assertions for a specific class or package. | +| `-esa\|-enablesystemassertions` | Set Java system property to enable system assertions. | +| `-dsa\|-disablesystemassertions` | Set Java system property to disable system assertions. | | `-D=` | Set a Java system property. | -| `-ea\|-enableassertions[: [...] \|:]` | Set Java system property to enable assertions. | -| `-da\|-disableassertions[: [...] \|:]` | Set Java system property to disable assertions. | -| `-Xsave` | Save the generated assembly (for debugging). | + +### Extra Options + +|                           Source                           |                                                              Description                                                               | +|---|---| +| `-X` | Displays command syntax and options for the `-X` command options. | +| `-Xsave\|-XXsave` | Save the generated assembly (for debugging). | | `-Xtime` | Time the execution. | | `-Xtrace:` | Displays all trace points with the given name. | | `-Xmethodtrace:` | Builds method trace into the specified output methods. | @@ -47,11 +59,17 @@ Command-line arguments passed to the main class. | `-Xnoglobbing` | Disable argument globbing. | | `-Xverify` | Enable strict class file verification. | | `-Xreference:/.dll` | Add a assembly (dll or exe) as reference to the classpath. This equals the C# code `Startup.addBootClassPathAssemby(Assembly.LoadFrom(name));`. | -| `-jar` | Run a jar file. | | `-Xdebug` | Enable debugging. | -| `-Xnoagent` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | | `-XX:+AllowNonVirtualCalls` | Allow non-virtual calls. | + +### Java Compatibility Options + +The Java HotSpot Virtual Machine is not supported by the `ikvm` tool. But several of the parameters will print warning messages if they are provided and do not halt execution of `ikvm`. + +|                           Source                           |                                                              Description                                                               | +|---|---| | `-XX:` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | +| `-Xnoagent` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | | `-Xms` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | | `-Xmx` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | | `-Xss` | For compatibility with java.exe. This option will be ignored and a warning will be print to the console. | From c88494a4a2fa980ee15e1c7f4f1b6ca970ed3500 Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Mon, 11 Jul 2022 00:35:17 +0700 Subject: [PATCH 3/5] docs/tools/ikvmc.md: Categorized options similarly to how they are categorized in the ikvmc help. --- docs/tools/ikvmc.md | 84 +++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/docs/tools/ikvmc.md b/docs/tools/ikvmc.md index 4107d2a563..c27db5711d 100644 --- a/docs/tools/ikvmc.md +++ b/docs/tools/ikvmc.md @@ -1,6 +1,8 @@ # ikvmc Tool -The `ikvmc` tool converts Java bytecode to .NET dll's and exe's. +> The `ikvmc` tool is considered an advanced option and it is recommended that new projects use the `IkvmReference` for the .NET SDK for most use cases. + +The `ikvmc` tool converts Java bytecode to .NET DLL and EXE files. - [Usage](#usage) - [Options](#options) @@ -27,50 +29,87 @@ Name of a Java `.class` or `.jar file`. May contain wildcards (`*.class`). ## Options -| Source | Description | +### Command Help + +|                           Source                           |                                                              Description                                                               | |---|---| | `-?\|-help` | Displays command syntax and options for the tool. | -| `@` | Read more options from the provided file. | + +### Output Files + +|                           Source                           |                                                              Description                                                               | +|---|---| | `-out:` | Specifies the name of the `outputfile`. Should have a .dll extension (if -target is library) or an .exe extension (if -target is exe or winexe). In most cases, if you omit this option, `ikvmc` will choose an output name based on the -target and the name of the input files. However, if you specify input files using wildcards, you must use this option to specify the output file. | | `-assembly:` | Specifies the name of the generated assembly. If omitted, the assembly name is (usually) the output filename. | +| `-version:` | Specifies the output assembly version. | +| `-fileversion:` | Specifies the output assembly file version. | | `-target:` | Specifies whether to generate an .exe or .dll. `target-type` is one of
  • `exe` - generates an executable that runs in a Windows command window
  • `winexe` - generates an .exe for GUI applications
  • `library` - generates a .dll
  • `module` - generates a .netmodule
On Linux, there is no difference between exe and winexe. | | `-platform:` | Limit which platforms this code can run on:
  • `x86` - 32 bit
  • `Itanium`
  • `x64`
  • `anycpu`
The default is `anycpu`. This can be helpful if your Java code use a dll via JNI. For example a 32 bit dll should also run on a 64 bit system as 32 bit application. | | `-keyfile:` | Uses `keyfilename` to sign the resulting assembly. | | `-key` | Use `keycontainer` to sign the assembly. | | `-delaysign` | Delay-sign the assembly. | -| `-version:` | Specifies the output assembly version. | -| `-fileversion:` | Specifies the output assembly file version. | -| `-main:` | Specifies the name of the class containing the main method. If omitted and the -target is exe or winexe, ikvmc searches for a qualifying main method and reports if it finds one. | -| `-r:\|-reference:` | If your Java code uses .NET API's, specify the dll's using this option. This option can appear more than once if more than one library is referenced. Wildcards are permitted (e.g. `C:\libs\*.dll`). | -| `-recurse:` | Processes all files matching `filespec` in and under the directory specified by filespec. Example: `-recurse:*.class` | -| `-nojni` | Do not generate JNI stub for native methods. | -| `-resource:=` | Includes path as a Java resource named `name`. | -| `-externalresource:=` | Reference file as Java resource. | + +### Input Files + + +|                           Source                           |                                                              Description                                                               | +|---|---| +| `-r:\|-reference:` | Add a reference to a class library DLL (.NET assembly). When building Java projects (`.jar` or `.class` files), this can be used to add dependent projects that had previously been compiled. The dependency must be compiled first. This option can appear more than once to reference multiple libraries. | +| `-recurse:` | Processes all files matching `filespec` in and under the directory specified by `filespec`. Example: `-recurse:*.class` | +| `-exclude:` | `filename` is a file containing a list of classes to exclude. | + +### Resources + +|                           Source                           |                                                              Description                                                               | +|---|---| | `-win32icon:` | Embed specified icon in output. | | `-win32manifest:` | Specify a Win32 manifest file (.xml). | +| `-resource:=` | Includes path as a Java resource named `name`. | +| `-externalresource:=` | Reference file as Java resource. | | `-compressresources` | Compress resources. | -| `-exclude:` | `filename` is a file containing a list of classes to exclude. | -| `-debug` | Generates debugging information in the output. Note that this is only helpful if the `.class` files contain debug information (compiled with the `javac -g` option). | -| `-srcpath:` | Specifies the location of source code. Use with `-debug`. The package of the class is appended to the specified `path` to locate the source code for the class. | -| `-Xtrace:` | Displays all trace points with `name`. | -| `-Xmethodtrace:` | Builds method trace into the specified output method. | + +### Code Generation + +|                           Source                           |                                                              Description                                                               | +|---|---| +| `-debug` | Generates debugging information in the output. Note that this is only helpful if the `.class` files contain debug information (compiled with the `javac -g` option). This option also produces somewhat less efficient CIL code. | | `-noautoserialization` | Disable automatic .NET serialization support. | | `-noglobbing` | Don't glob the arguments passed to `-main`. | | `-nojni` | Do not generate JNI stub for native methods. | | `-opt:fields` | Remove unused private fields. | | `-removeassertions` | Remove all assert statements. | | `-strictfinalfieldsemantics` | Don't allow final fields to be modified outside of initializer methods. | + +### Errors and Warnings + +|                           Source                           |                                                              Description                                                               | +|---|---| | `-nowarn:` | Suppress specified warnings. | | `-warnaserror` | Treat all warnings as errors. | | `-warnaserror:` | Treat specified warnings as errors. | | `-writeSuppressWarningsFile:` | Write response file with `-nowarn:` options to suppress all encountered warnings. | + + +### Miscellaneous + +|                           Source                           |                                                              Description                                                               | +|---|---| +| `@` | Read more options from the provided file. | | `-nologo` | Suppress compiler copyright message. | -| `-srcpath:` | Prepend path and package name to source file. | + +### Advanced + +|                           Source                           |                                                              Description                                                               | +|---|---| +| `-main:` | Specifies the name of the class containing the main method. If omitted and the -target is exe or winexe, ikvmc searches for a qualifying main method and reports if it finds one. | +| `-srcpath:` | Specifies the location of source code. Use with `-debug`. The package of the class is appended to the specified `path` to locate the source code for the class. | | `-apartment:` | Apply a thread apartment state attribute to `-main` based on the selected option:
  • `sta` - Apply `STAThreadAttribute`
  • `mta` - Apply `MTAThreadAttribute`
  • `none` - Apply no attribute
The default option is `sta`. | | `-D=` | Set a Java system property (at runtime). | -| `-ea\|-enableassertions[: [...] \|:]` | Set Java system property to enable assertions. | -| `-da\|-disableassertions[: [...] \|:]` | Set Java system property to disable assertions. | +| `-ea\|-enableassertions[:[\|]]` | Set Java system property to enable assertions. A class name or package name can be specified to enable assertions for a specific class or package. | +| `-da\|-disableassertions[:[\|]]` | Set Java system property to disable assertions. A class name or package name can be specified to disable assertions for a specific class or package. | | `-nostacktraceinfo` | Don't create metadata to emit rich stack traces. | +| `-Xtrace:` | Displays all trace points with `name`. | +| `-Xmethodtrace:` | Builds method trace into the specified output method. | | `-privatepackage:` | Mark all classes with a package name starting with `prefix` as internal to the assembly. | | `-publicpackage:` | Mark all classes with a package name starting with `prefix` as public to the assembly. | | `-time` | Display timing statistics. | @@ -87,12 +126,13 @@ Name of a Java `.class` or `.jar file`. May contain wildcards (`*.class`). | `-proxy:` | Undocumented. | | `-nojarstubs` | Undocumented temporary option to mitigate risk. | | `-w4` | Undocumented option to compile core class libraries with, to disable MethodParameter attribute. | -| `-strictfinalfieldsemantics` | Undocumented. | -| `-remap` | Undocumented. | +| `-strictfinalfieldsemantics` | Undocumented. For internal use. | +| `-remap` | Undocumented. For internal use. | +| `-runtime` | Specifies the `IKVM.Runtime.dll` library to use. Not fully functional. | ## Notes -The ikvmc tool generates .NET assemblies from Java class files and jar files. It converts the Java bytecode in the input files to .NET CIL. Use it to produce +The `ikvmc` tool generates .NET assemblies from Java class files and jar files. It converts the Java bytecode in the input files to .NET CIL. Use it to produce - .NET executables (`-target:exe` or `-target:winexe`) - .NET libraries (`-target:library`) From 550e34ea87bc971ebe27c7367588271a5744ee14 Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Mon, 11 Jul 2022 00:36:25 +0700 Subject: [PATCH 4/5] docs/tools/ikvmstub.md: Added missing options --- docs/tools/ikvmstub.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/tools/ikvmstub.md b/docs/tools/ikvmstub.md index be84188c37..4293fe7e07 100644 --- a/docs/tools/ikvmstub.md +++ b/docs/tools/ikvmstub.md @@ -14,11 +14,11 @@ Name of an assembly. May be a fully-qualified path. ## Options -| Source | Description | +|                           Source                           |                                                              Description                                                               | |---|---| | No `` provided | Displays command syntax and options for the tool. | | `-out:` | Specifies the name of the `outputfile`. | -| `-r:\|-reference:` | Reference an assembly. | +| `-r:\|-reference:` | Reference a class library DLL (.NET assembly). This option may be specified more than once to reference multiple DLLs. | | `-japi` | Generate `.jar` suitable for comparison with japitools. | | `-skiperror` | Continue when errors are encountered. | | `-shared` | Process all assemblies in shared group. | @@ -27,6 +27,9 @@ Name of an assembly. May be a fully-qualified path. | `-namespace:` | Only include types from specified `namespace`. This option may be specified more than once. | | `-forwarders` | Export forwarded types too. | | `-parameters` | Emit Java 8 classes with parameter names. | +| `-bootstrap` | Undocumented. | +| `-serialver` | Deprecated. Use `-japi` instead. | + ## Notes From 15bb9a3a0b510777b140b1a7e7ed67d8ea3e6108 Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Mon, 10 Oct 2022 20:56:33 +0700 Subject: [PATCH 5/5] ikvmc.md: Added details about -exclude option --- docs/tools/ikvmc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools/ikvmc.md b/docs/tools/ikvmc.md index c27db5711d..68056cd23e 100644 --- a/docs/tools/ikvmc.md +++ b/docs/tools/ikvmc.md @@ -56,7 +56,7 @@ Name of a Java `.class` or `.jar file`. May contain wildcards (`*.class`). |---|---| | `-r:\|-reference:` | Add a reference to a class library DLL (.NET assembly). When building Java projects (`.jar` or `.class` files), this can be used to add dependent projects that had previously been compiled. The dependency must be compiled first. This option can appear more than once to reference multiple libraries. | | `-recurse:` | Processes all files matching `filespec` in and under the directory specified by `filespec`. Example: `-recurse:*.class` | -| `-exclude:` | `filename` is a file containing a list of classes to exclude. | +| `-exclude:` | `filename` is a file containing a list of class names to exclude. The file may contain a single .NET-compatible regular expression per line. If the line starts with a `\`, it will be ignored as a comment. | ### Resources @@ -191,4 +191,4 @@ First it generates a library `mylib.dll` from `mylib.jar`. Then it generates an - [Components](../components.md) - [Convert a .jar file to a .dll](../convert-a-jar-file-to-a-dll.md) - [Tools](index.md) -- [Tutorial](../tutorial.md) \ No newline at end of file +- [Tutorial](../tutorial.md)