ikvmnet / ikvm

A Java Virtual Machine and Bytecode-to-IL Converter for .NET
Other
1.15k stars 110 forks source link

Cannot replicate a simple one-line app from java #450

Closed patanne closed 7 months ago

patanne commented 7 months ago

I am trying to build a proof of concept console app project that uses xerces2-J to validate XML against a XML Schema 1.1 XSD. I am using Jetbrains Rider for C#/.net and IntelliJ for Java. I am using .net 8.0 and JDK 11 for their respective platforms. I am also using the specific download, Xerces-J 2.12.2-xml-schema-1.1.

I am being tripped up right away when trying to create a SchemaFactory. In IntelliJ this line of code works...

SchemaFactory factory =
SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");

In .NET you get the somewhat vague exception,

No SchemaFactory that implements the schema language specified by: http://www.w3.org/XML/XMLSchema/v1.1 could be loaded.

Going back to Java I dug further to learn that the factory supporting XSD 1.1 is org.apache.xerces.jaxp.validation.XMLSchema11Factory

Attempting to force use of that factory class I changed out the line of code above for this...

SchemaFactory factory =
SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1",@"org.apache.xerces.jaxp.validation.XMLSchema11Factory",null);

This line led to the slightly more descriptive exception,

Factory org.apache.xerces.jaxp.validation.XMLSchema11Factory could not be loaded to implement the schema language specified by: http://www.w3.org/XML/XMLSchema/v1.1.

I then attempted to cut out the whole factory resolution process by doing this...

SchemaFactory factory =
XMLSchema11Factory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");

That led back to the first, less descriptive exception.

When attempting to debug it appears I cannot step into the Java code from the jar file handled by IKVM, so I can go no further trying to identify the root cause.

I know the generated xerces dll is loading and can be referenced. Aside from namespace intellisense functioning as expected, these lines yield the correct results...

using Version = org.apache.xerces.impl.Version;
var version = Version.getVersion();

My project file has the following that is relevant...

<ItemGroup>
  <PackageReference Include="IKVM" Version="8.7.1" />
</ItemGroup>

<ItemGroup>
    <IkvmReference Include="include\org.eclipse.wst.xml.xpath2.processor_1.2.1.jar">
        <AssemblyName>eclipse-xpath2</AssemblyName>
        <AssemblyVersion>1.2.1.0</AssemblyVersion>
        <AssemblyFileVersion>1.2.1.0</AssemblyFileVersion>
    </IkvmReference>
    <IkvmReference Include="include\cupv10k-runtime.jar">
        <AssemblyName>cup-runtime</AssemblyName>
        <AssemblyVersion>1.0.0</AssemblyVersion>
        <AssemblyFileVersion>1.0.0</AssemblyFileVersion>
    </IkvmReference>
    <IkvmReference Include="include\xercesImpl.jar">
        <AssemblyName>xerces</AssemblyName>
        <AssemblyVersion>2.12.2.0</AssemblyVersion>
        <AssemblyFileVersion>2.12.2.0</AssemblyFileVersion>
        <Debug>true</Debug>
        <References>include/cupv10k-runtime.jar;include/org.eclipse.wst.xml.xpath2.processor_1.2.1.jar</References>
    </IkvmReference>
</ItemGroup>

The results are the same with or without the above 'references' tag in the project file.

Any idea what I am missing?

wasabii commented 7 months ago

I'm not really sure how this library works internally either, but it sounds like the type of thing that happens if you don't preload required assemblies up front. For instance, you have three assemblies being generated. But if one is using Java reflection to find classes in the other, you'll have to make sure the assembly is loaded before it tries. It can't see classes just from dlls on disk.

Assembly. Load?

wasabii commented 7 months ago

Oh. Also, arrive you're not using MavenReference, you'll probably want to say the class loader for each reference to AppDomainAssemblyClassLoader.

patanne commented 7 months ago

Thank you! That did it.