Re: Duplicate class definition

Yves Langisch <[email protected]> Wed, 23 Dec 2015 08:56:23 +0100
Newsgroups gmane.comp.java.ikvm.devel
Message-ID <[email protected]>
Hi Jeroen,

Please find attached a patch for an additional switch ‚-skipDuplicates‘.

Best,
Yves


> On 18 Dec 2015, at 12:33 , Jeroen Frijters <[email protected]> wrote:
> 
> Hi Yves,
> 
> You can easily write a tool to list the duplicates to a file during your build process, so it's not that big a deal.
> 
> Compatibility means that there is a lot of weird Java code that expects weird things.
> 
> If you want to add a switch ikvmc, I'll certainly consider the patch if you submit it :-)
> 
> Regards,
> Jeroen
> 
>> -----Original Message-----
>> From: Yves Langisch [mailto:[email protected]]
>> Sent: Friday, December 18, 2015 9:48
>> To: Jeroen Frijters <[email protected]>; ikvm-developers <ikvm-
>> [email protected]>
>> Subject: Re: [Ikvm-developers] Duplicate class definition
>> 
>> Hi Jeroen,
>> 
>> What does compatibility mean? Since the set of duplicate classes is
>> quite huge the exclude option is not a viable option for us.
>> 
>> Is there any chance to add an additional flag to ikvmc whether duplicate
>> classes are included as resources or completely ignored?
>> 
>> Thanks
>> Yves
>> 
>> On 17.12.2015 18:56, Jeroen Frijters wrote:
>>> Hi Yves,
>>> 
>>> The classes that it can't compile are included as resources (for
>> compatibility). If you're willing to do the work, you can create a file
>> listing the classes that should be excluded and pass it to the ikvmc -
>> exclude:<filename> option.
>>> 
>>> Regards,
>>> Jeroen
>>> 
>>>> -----Original Message-----
>>>> From: Yves Langisch [mailto:[email protected]]
>>>> Sent: Thursday, December 17, 2015 18:26
>>>> To: Jeroen Frijters <[email protected]>; ikvm-developers <ikvm-
>>>> [email protected]>
>>>> Subject: Re: [Ikvm-developers] Duplicate class definition
>>>> 
>>>> Hi Jeroen,
>>>> 
>>>> Thanks a lot, that fixed the linkage error.
>>>> 
>>>> Another issue in this scenario I have is that the secondly generated
>>>> DLL
>>>> (app.dll) which should only contain a few additional classes has at
>>>> least the same size as the referenced core.dll (12MB). The jar set to
>>>> convert is more or less the same for both DLLs (cannot easily changed
>>>> due to our build process). For me it looks like the classes that
>>>> ikvmc correctly claims as duplicates are still part of the resulting
>>>> app.dll but not visible (at least invisible in the object browser).
>>>> 
>>>> Any ideas?
>>>> 
>>>> Thanks
>>>> Yves
>>>> 
>>>> On 16.11.2015 15:00, Jeroen Frijters wrote:
>>>>> Hi,
>>>>> 
>>>>> This is now fixed in cvs.
>>>>> 
>>>>> Regards,
>>>>> Jeroen
>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Yves Langisch [mailto:[email protected]]
>>>>>> Sent: Friday, November 13, 2015 15:20
>>>>>> To: ikvm-developers <[email protected]>
>>>>>> Subject: [Ikvm-developers] Duplicate class definition
>>>>>> 
>>>>>> Hi there,
>>>>>> 
>>>>>> Sometimes during authentication in my application I get the
>>>>>> following
>>>>>> exception:
>>>>>> 
>>>>>> Caused by: java.util.concurrent.ExecutionException:
>>>>>> java.lang.LinkageError: duplicate class definition:
>>>>>> com.jcraft.jsch.agentproxy.connector.PageantConnector$User32
>>>>>> 	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
>>>>>> 	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
>>>>>> 	...
>>>>>> Caused by: java.lang.LinkageError: duplicate class definition:
>>>>>> com.jcraft.jsch.agentproxy.connector.PageantConnector$User32
>>>>>> 	at Java_java_lang_ClassLoader.defineClass1(Unknown Source)
>>>>>> 	at IKVM.Internal.AssemblyClassLoader.DefineDynamic(Unknown Source)
>>>>>> 	at IKVM.Internal.AssemblyClassLoader.LoadDynamic(Unknown Source)
>>>>>> 	at IKVM.Internal.AssemblyClassLoader.LoadClassImpl(Unknown Source)
>>>>>> 	at IKVM.Internal.ClassLoaderWrapper.LoadClass(Unknown Source)
>>>>>> 	at IKVM.Runtime.ByteCodeHelper.LoadTypeWrapper(Unknown Source)
>>>>>> 	at IKVM.Runtime.ByteCodeHelper.DynamicLoadMethodHandleImpl(Unknown
>>>>>> Source)
>>>>>> 	at IKVM.Runtime.ByteCodeHelper.DynamicBinderMemberLookup(Unknown
>>>>>> Source)
>>>>>> 	at
>>>>>> com.jcraft.jsch.agentproxy.connector.PageantConnector.<init>(Pagean
>>>>>> tC
>>>>>> onn
>>>>>> ector.java:57)
>>>>>> 	…
>>>>>> 
>>>>>> Background:
>>>>>> 
>>>>>> * two relevant DLLs (app.dll, core.ll)
>>>>>> * core.dll is an IKVM converted library containing many 3rd party
>>>>>> Java jars
>>>>>> * app.dll is converted with /reference:core.dll and contains most
>>>>>> of the jars in core.dll already (and some more) -> conversion leads
>>>>>> to duplicate class warnings
>>>>>> 
>>>>>> As far as I can see there are no duplicate classes in both DLLs.
>>>>>> Referring to the stack trace, PageantConnector is in core.dll, the
>>>>>> User32 interface in app.dll, if this makes any difference.
>>>>>> 
>>>>>> Any ideas? Thanks!
>>>>>> 
>>>>>> -
>>>>>> Yves
>>>>>> 
>>>>>> -------------------------------------------------------------------
>>>>>> --
>>>>>> ---
>>>>>> ------
>>>>>> _______________________________________________
>>>>>> Ikvm-developers mailing list
>>>>>> [email protected]
>>>>>> https://lists.sourceforge.net/lists/listinfo/ikvm-developers
>

------------------------------------------------------------------------------

_______________________________________________
Ikvm-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ikvm-developers
patch.diff (application/octet-stream, 3.3 KB)
? patch.diff
Index: ikvmc/Compiler.cs
===================================================================
RCS file: /cvsroot/ikvm/ikvm/ikvmc/Compiler.cs,v
retrieving revision 1.169
diff -w -u -r1.169 Compiler.cs
--- ikvmc/Compiler.cs	26 Jun 2015 11:22:19 -0000	1.169
+++ ikvmc/Compiler.cs	23 Dec 2015 07:53:38 -0000
@@ -459,6 +459,7 @@
 		Console.Error.WriteLine("-reference:<filespec>          Reference an assembly (short form -r:<filespec>)");
 		Console.Error.WriteLine("-recurse:<filespec>            Recurse directory and include matching files");
 		Console.Error.WriteLine("-exclude:<filename>            A file containing a list of classes to exclude");
+		Console.Error.WriteLine("-skipDuplicates                Do not add duplicate classes as resources");
 		Console.Error.WriteLine();
 		Console.Error.WriteLine("                      - RESOURCES -");
 		Console.Error.WriteLine("-fileversion:<version>         File version");
@@ -787,6 +788,10 @@
 				{
 					ProcessExclusionFile(ref options.classesToExclude, s.Substring(9));
 				}
+                else if (s == "-skipDuplicates")
+                {
+                    options.skipDuplicates = true;
+                }
 				else if(s.StartsWith("-version:"))
 				{
 					string str = s.Substring(9);
Index: ikvmc/CompilerClassLoader.cs
===================================================================
RCS file: /cvsroot/ikvm/ikvm/ikvmc/CompilerClassLoader.cs,v
retrieving revision 1.278
diff -w -u -r1.278 CompilerClassLoader.cs
--- ikvmc/CompilerClassLoader.cs	26 Jun 2015 11:22:19 -0000	1.278
+++ ikvmc/CompilerClassLoader.cs	23 Dec 2015 07:53:38 -0000
@@ -756,6 +756,14 @@
 							}
 							continue;
 						}
+					    if (options.skipDuplicates && IsClass(item.Name))
+					    {
+                            string className = item.Name.Substring(0, item.Name.Length - 6).Replace('/', '.');
+					        if (classesToCompile.Contains(className))
+					        {
+					            continue;
+					        }
+                        }
 						ZipEntry zipEntry = item.ZipEntry;
 						if (options.compressedResources || zipEntry.CompressionMethod != CompressionMethod.Stored)
 						{
@@ -2642,6 +2650,12 @@
 			return StaticCompiler.errorCount == 0 ? 0 : 1;
 		}
 
+	    private static bool IsClass(string name)
+	    {
+	        return name.EndsWith(".class", StringComparison.Ordinal) && name.Length > 6 &&
+	               name.IndexOf('.') == name.Length - 6;
+	    }
+
 		private static int CreateCompiler(CompilerOptions options, ref CompilerClassLoader loader, ref bool compilingCoreAssembly)
 		{
 			Tracer.Info(Tracer.Compiler, "JVM.Compile path: {0}, assembly: {1}", options.path, options.assembly);
@@ -2690,9 +2704,7 @@
 				foreach (Jar.Item item in jar)
 				{
 					string name = item.Name;
-					if (name.EndsWith(".class", StringComparison.Ordinal)
-						&& name.Length > 6
-						&& name.IndexOf('.') == name.Length - 6)
+					if (IsClass(name))
 					{
 						string className = name.Substring(0, name.Length - 6).Replace('/', '.');
 						if (h.ContainsKey(className))
@@ -3467,6 +3479,7 @@
 		internal string[] peerReferences;
 		internal bool crossReferenceAllPeers = true;
 		internal string[] classesToExclude;		// only used during command line parsing
+	    internal bool skipDuplicates;
 		internal FileInfo remapfile;
 		internal Dictionary<string, string> props;
 		internal bool noglobbing;