Getting java.net.MalformedURLException in MonoDeve

2019-02-24 21:14发布

问题:

Hey I am new to MonoDeveloper. I am trying to port libgdx code to iOS platform. My Libgdx code runs perfectly on desktop & Android phone. But when i run it on iPhone simulator with MonoDeveloper its giving me this error:

Unhandled Exception: 0   iosgame   
[ERROR] FATAL UNHANDLED EXCEPTION: java.net.MalformedURLException: unknown protocol: file.
0x000e8932 mono_handle_exception_internal_first_pass + 3058 1 iosgame                             
0x000ea012 mono_handle_exception_internal + 1602 2   iosgame                     
0x000eab5f mono_handle_exception + 47 3   iosgame                     
0x0012dcb2 mono_x86_throw_exception + 306 4   ???                     
0x0b73df8f 0x0 + 192143247 at java.net.URL..ctor (java.net.URL,string)
<IL 0x00004, 0x00018> at java.net.URL..ctor (string) 
<IL 0x00003, 0x00018> at java.net.URI.toURL () 
<IL 0x00023, 0x00064> at IKVM.Internal.AssemblyClassLoader.MakeResourceURL(System.Reflection.Assembly,string) 
<IL 0x00016, 0x0006c> at IKVM.Internal.AssemblyClassLoader/AssemblyLoader.FindResources(string) 
<IL 0x0003c, 0x00084> at IKVM.Internal.AssemblyClassLoader/<GetResourcesImpl>c__Iterator0.MoveNext() 
<IL 0x00068, 0x00070> at IKVM.Internal.AssemblyClassLoader/<GetResourcesImpl>c__Iterator0.MoveNext() 
<IL 0x003dc, 0x0069f> at IKVM.NativeCode.ikvm.runtime.AssemblyClassLoader.getResource(java.lang.ClassLoader,System.Reflection.Assembly,string) 
<IL 0x00034, 0x0009c> at ikvm.runtime.AssemblyClassLoader.getResource(java.lang.ClassLoader,System.Reflection.Assembly,string) 
<IL 0x00006, 0x00018> at ikvm.runtime.AssemblyClassLoader.getResource (string) 
<IL 0x00000, 0x0001c>

Kindly give me suggestion where i am wrong.

回答1:

This is probably a bug in libgdx or in IKVM, the library used to port Java code to the the .NET/Mono runtime. Have you reported it to the libgdx developers?



回答2:

My guess is that the MonoTouch port of IKVM doesn't include the "file" protocol handler.



回答3:

I found the answer to the issue myself.

In the stack trace, it'll mention which line of your Java code is calling the MalformedURLException. So for example: Example.java:208

Locate line 208 of Example.java, and see what file it's stumbling on.

Next, locate this file inside Xamarin/mono studio and right click on it.
Then go down to "Build Option" > "BundleResource".



回答4:

Based on a past question (from the same user) I think this is the output of a chain reaction. Apple recently began to refuse application executables bigger than 60MB.

That's huge, a basic hello world application created with Xamarin.iOS is under 3 MB and that's the total application size. The executable itself is under 2.2MB and includes the Mono runtime, the linked base class libraries (BCL) and the unlinked user code.

Now this 2.2MB size is achieved because the BCL is linked (by default Link SDK is used for device builds). That means everything that is not used, in the BCL, is removed. If the BCL was not linked (it can be disabled if you're curious) then the executable size would be 46 MB - more than 20x bigger! (and that's part of the reasons why you should never disable the linker on device builds).

LibGDX is a Java library. It can work with Xamarin.iOS by being converted to .NET using IKVM. That converts the GDX library and the Java class libraries. All of this is user code (i.e. stuff you added) and not SDK code (i.e. code shipped by Xamarin). IOW the linker does not, by default, remove anything from GDX (or IKVM libraries).

So, by default, everything in GDX and Java (class lib) is being AOT'ed into the native executable - leading it over Apple's limit (which was the previous question).

The previous answer was to use Link all assemblies, IOW run the linker on all the application managed code. That removes a lot of unused code and results in smaller applications and executable size (see the hello world example above).

However it goes back to the main linker limitation. It use static analysis to detect unused code - and reflection (from .NET or Java) is dynamic. So the linker needs help to preserve (using [Preserve] attribute or an XML file) code used thru reflection.

I have not seen the Java code handling protocols - but I'm pretty sure it use reflection to load a type based on the scheme (e.g. file) and that type(s) needs to be preserved to work correctly at runtime. Once preserved I'm sure the application will work properly (and without being improperly large).



回答5:

Is there a point after the "unknown protocol: file"? In this case a classpath URI is wrong. It look like that there is any setting wrongs. A file URL should start with:

file:

And the error message look like that it start with:

file.