private static Assembly GetAssemblyFromClass(jlClass clazz) { TypeWrapper wrapper = TypeWrapper.FromClass(clazz); AssemblyClassLoader_ acl = wrapper.GetClassLoader() as AssemblyClassLoader_; return(acl != null?acl.GetAssembly(wrapper) : null); }
public static global::java.util.Enumeration getResources(global::java.lang.ClassLoader classLoader, Assembly assembly, string name) { #if FIRST_PASS return(null); #else global::java.util.Vector v = new global::java.util.Vector(); if (assembly != null) { IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); foreach (global::java.net.URL url in wrapper.GetResources(name)) { v.addElement(url); } } // we'll only generate a stub class if there isn't already a resource with this name if (v.isEmpty()) { global::java.net.URL curl = GetClassResource(classLoader, assembly, name); if (curl != null) { v.addElement(curl); } } return(v.elements()); #endif }
public static void lazyDefinePackages(global::java.lang.ClassLoader _this) { #if !FIRST_PASS AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); global::java.net.URL sealBase = GetCodeBase(wrapper.MainAssembly); global::java.util.jar.Manifest manifest = GetManifest(_this); global::java.util.jar.Attributes attr = null; if (manifest != null) { attr = manifest.getMainAttributes(); } string[] packages = wrapper.GetPackages(); for (int i = 0; i < packages.Length; i++) { string name = packages[i]; if (_this.getPackage(name) == null) { global::java.util.jar.Attributes entryAttr = null; if (manifest != null) { entryAttr = manifest.getAttributes(name.Replace('.', '/') + '/'); } _this.definePackage(name, GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_TITLE, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VERSION, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VENDOR, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VENDOR, entryAttr, attr), "true".Equals(GetAttributeValue(global::java.util.jar.Attributes.Name.SEALED, entryAttr, attr), StringComparison.OrdinalIgnoreCase) ? sealBase : null); } } #endif }
public static global::java.net.URL findResource(global::java.lang.ClassLoader _this, string name) { #if !FIRST_PASS AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); foreach (global::java.net.URL url in wrapper.FindResources(name)) { return(url); } #endif return(null); }
public static global::java.net.URL GetManifest(Assembly assembly) { #if FIRST_PASS return(null); #else IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); foreach (global::java.net.URL url in wrapper.FindResources("META-INF/MANIFEST.MF")) { return(url); } return(null); #endif }
internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, string path, bool targetIsModule, string assemblyName, Dictionary<string, ClassItem> classes) : base(options.codegenoptions, null) { this.referencedAssemblies = referencedAssemblies; this.options = options; this.classes = classes; this.assemblyName = assemblyName; FileInfo assemblyPath = new FileInfo(path); this.assemblyFile = assemblyPath.Name; this.assemblyDir = assemblyPath.DirectoryName; this.targetIsModule = targetIsModule; Tracer.Info(Tracer.Compiler, "Instantiate CompilerClassLoader for {0}", assemblyName); }
public static Assembly[] FindResourceAssemblies(Assembly assembly, string name, bool firstOnly) { IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); Assembly[] assemblies = wrapper.FindResourceAssemblies(name, firstOnly); if (assemblies == null || assemblies.Length == 0) { Tracer.Info(Tracer.ClassLoading, "Failed to find resource \"{0}\" in {1}", name, assembly.FullName); return(null); } foreach (Assembly asm in assemblies) { Tracer.Info(Tracer.ClassLoading, "Found resource \"{0}\" in {1}", name, asm.FullName); } return(assemblies); }
public static string getAssemblyName(jlClass c) { TypeWrapper wrapper = TypeWrapper.FromClass(c); ClassLoaderWrapper loader = wrapper.GetClassLoader(); IKVM.Internal.AssemblyClassLoader acl = loader as IKVM.Internal.AssemblyClassLoader; if (acl != null) { return(acl.GetAssembly(wrapper).FullName); } else { return(((GenericClassLoaderWrapper)loader).GetName()); } }
public static global::java.net.URL getResource(global::java.lang.ClassLoader classLoader, Assembly assembly, string name) { #if FIRST_PASS return(null); #else if (assembly != null) { IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); foreach (global::java.net.URL url in wrapper.GetResources(name)) { return(url); } } return(GetClassResource(classLoader, assembly, name)); #endif }
// NOTE the array may contain duplicates! public static string[] GetPackages(Assembly assembly) { IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); string[] packages = new string[0]; foreach (Module m in wrapper.MainAssembly.GetModules(false)) { object[] attr = m.GetCustomAttributes(typeof(PackageListAttribute), false); foreach (PackageListAttribute p in attr) { string[] mp = p.GetPackages(); string[] tmp = new string[packages.Length + mp.Length]; Array.Copy(packages, 0, tmp, 0, packages.Length); Array.Copy(mp, 0, tmp, packages.Length, mp.Length); packages = tmp; } } return(packages); }
private static IEnumerable <global::java.net.URL> FindResources(string name) { List <IKVM.Internal.AssemblyClassLoader> done = new List <IKVM.Internal.AssemblyClassLoader>(); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { if (!ReflectUtil.IsDynamicAssembly(asm)) { IKVM.Internal.AssemblyClassLoader acl = IKVM.Internal.AssemblyClassLoader.FromAssembly(asm); if (!done.Contains(acl)) { done.Add(acl); foreach (global::java.net.URL url in acl.FindResources(name)) { yield return(url); } } } } }
public static void lazyDefinePackages(global::java.lang.ClassLoader _this) { #if !FIRST_PASS AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); global::java.net.URL sealBase = GetCodeBase(wrapper.MainAssembly); foreach (KeyValuePair <string, string[]> packages in wrapper.GetPackageInfo()) { global::java.util.jar.Manifest manifest = null; global::java.util.jar.Attributes attr = null; if (packages.Key != null) { global::java.util.jar.JarFile jarFile = new global::java.util.jar.JarFile(VirtualFileSystem.GetAssemblyResourcesPath(wrapper.MainAssembly) + packages.Key); manifest = jarFile.getManifest(); } if (manifest != null) { attr = manifest.getMainAttributes(); } foreach (string name in packages.Value) { if (_this.getPackage(name) == null) { global::java.util.jar.Attributes entryAttr = null; if (manifest != null) { entryAttr = manifest.getAttributes(name.Replace('.', '/') + '/'); } _this.definePackage(name, GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_TITLE, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VERSION, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.SPECIFICATION_VENDOR, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION, entryAttr, attr), GetAttributeValue(global::java.util.jar.Attributes.Name.IMPLEMENTATION_VENDOR, entryAttr, attr), "true".Equals(GetAttributeValue(global::java.util.jar.Attributes.Name.SEALED, entryAttr, attr), StringComparison.OrdinalIgnoreCase) ? sealBase : null); } } } #endif }
public static global::java.lang.Class LoadClass(object classLoader, Assembly assembly, string name) { try { TypeWrapper tw = null; if (classLoader == null) { tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(name); } else if (assembly != null) { AssemblyClassLoader_ acl = global::IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); tw = acl.GetLoadedClass(name); if (tw == null) { tw = acl.LoadGenericClass(name); } if (tw == null) { tw = acl.LoadReferenced(name); } if (tw == null) { throw new ClassNotFoundException(name); } } else { // this must be a GenericClassLoader tw = ((GenericClassLoader)ClassLoaderWrapper.GetClassLoaderWrapper(classLoader)).LoadClassByDottedName(name); } Tracer.Info(Tracer.ClassLoading, "Loaded class \"{0}\" from {1}", name, classLoader == null ? "boot class loader" : classLoader); return(tw.ClassObject); } catch (RetargetableJavaException x) { Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, classLoader == null ? "boot class loader" : classLoader); throw x.ToJava(); } }
public static global::java.lang.Class loadClass(global::java.lang.ClassLoader _this, string name, bool resolve) { #if FIRST_PASS return(null); #else try { if (!global::java.lang.ClassLoader.checkName(name)) { throw new ClassNotFoundException(name); } AssemblyClassLoader_ wrapper = (AssemblyClassLoader_)ClassLoaderWrapper.GetClassLoaderWrapper(_this); TypeWrapper tw = wrapper.LoadClass(name); if (tw == null) { Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); global::java.lang.Throwable.suppressFillInStackTrace = true; throw new global::java.lang.ClassNotFoundException(name); } Tracer.Info(Tracer.ClassLoading, "Loaded class \"{0}\" from {1}", name, _this); return(tw.ClassObject); } catch (ClassNotFoundException x) { Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); throw new global::java.lang.ClassNotFoundException(x.Message); } catch (ClassLoadingException x) { Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); throw x.InnerException; } catch (RetargetableJavaException x) { Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); throw x.ToJava(); } #endif }
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); AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName(); bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly); List<Assembly> references = new List<Assembly>(); foreach(Assembly reference in options.references ?? new Assembly[0]) { references.Add(reference); allReferencesAreStrongNamed &= IsSigned(reference); Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName); // if it's an IKVM compiled assembly, make sure that it was compiled // against same version of the runtime foreach(AssemblyName asmref in reference.GetReferencedAssemblies()) { if(asmref.Name == runtimeAssemblyName.Name) { if(IsSigned(StaticCompiler.runtimeAssembly)) { // TODO we really should support binding redirects here to allow different revisions to be mixed if(asmref.FullName != runtimeAssemblyName.FullName) { throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); } } else { if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0) { throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); } } } } } Tracer.Info(Tracer.Compiler, "Parsing class files"); // map the class names to jar entries Dictionary<string, Jar.Item> h = new Dictionary<string, Jar.Item>(); List<string> classNames = new List<string>(); foreach (Jar jar in options.jars) { if (options.IsResourcesJar(jar)) { continue; } foreach (Jar.Item item in jar) { string name = item.Name; if (name.EndsWith(".class", StringComparison.Ordinal) && name.Length > 6 && name.IndexOf('.') == name.Length - 6) { string className = name.Substring(0, name.Length - 6).Replace('/', '.'); if (h.ContainsKey(className)) { StaticCompiler.IssueMessage(Message.DuplicateClassName, className); Jar.Item itemRef = h[className]; if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar) { // the previous class stays, because it was either in an earlier jar or we're processing the classes.jar // which contains the classes loaded from the file system (where the first encountered class wins) continue; } else { // we have a jar that contains multiple entries with the same name, the last one wins h.Remove(className); classNames.Remove(className); } } h.Add(className, item); classNames.Add(className); } } } if (options.assemblyAttributeAnnotations == null) { // look for "assembly" type that acts as a placeholder for assembly attributes Jar.Item assemblyType; if (h.TryGetValue("assembly", out assemblyType)) { try { byte[] buf = assemblyType.GetData(); ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null); // NOTE the "assembly" type in the unnamed package is a magic type // that acts as the placeholder for assembly attributes if (f.Name == "assembly" && f.Annotations != null) { options.assemblyAttributeAnnotations = f.Annotations; // HACK remove "assembly" type that exists only as a placeholder for assembly attributes h.Remove(f.Name); assemblyType.Remove(); StaticCompiler.IssueMessage(Message.LegacyAssemblyAttributesFound); } } catch (ClassFormatError) { } } } // now look for a main method if (options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) { foreach (string className in classNames) { try { byte[] buf = h[className].GetData(); ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null); if (f.Name == className) { foreach (ClassFile.Method m in f.Methods) { if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); options.mainClass = f.Name; goto break_outer; } } } } catch (ClassFormatError) { } } break_outer: ; } if(options.guessFileKind && options.mainClass == null) { options.target = PEFileKinds.Dll; } if(options.target == PEFileKinds.Dll && options.mainClass != null) { throw new FatalCompilerErrorException(Message.MainClassRequiresExe); } if(options.target != PEFileKinds.Dll && options.mainClass == null) { throw new FatalCompilerErrorException(Message.ExeRequiresMainClass); } if(options.target == PEFileKinds.Dll && options.props.Count != 0) { throw new FatalCompilerErrorException(Message.PropertiesRequireExe); } if(options.path == null) { if(options.target == PEFileKinds.Dll) { if(options.targetIsModule) { options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".netmodule"); } else { options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".dll"); } } else { options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".exe"); } StaticCompiler.IssueMessage(Message.OutputFileIs, options.path.ToString()); } if(options.targetIsModule) { if(options.classLoader != null) { throw new FatalCompilerErrorException(Message.ModuleCannotHaveClassLoader); } // TODO if we're overwriting a user specified assembly name, we need to emit a warning options.assembly = options.path.Name; } Tracer.Info(Tracer.Compiler, "Constructing compiler"); AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count]; for(int i = 0; i < references.Count; i++) { AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]); if (Array.IndexOf(referencedAssemblies, acl) != -1) { StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName); } referencedAssemblies[i] = acl; } loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h, compilingCoreAssembly); loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) { Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile); System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root)); ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement); ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute); FileStream fs; try { fs = options.remapfile.OpenRead(); } catch(Exception x) { throw new FatalCompilerErrorException(Message.ErrorReadingFile, options.remapfile, x.Message); } try { XmlTextReader rdr = new XmlTextReader(fs); IKVM.Internal.MapXml.Root.xmlReader = rdr; IKVM.Internal.MapXml.Root map; try { map = (IKVM.Internal.MapXml.Root)ser.Deserialize(rdr); } catch(InvalidOperationException x) { throw new FatalCompilerErrorException(Message.ErrorParsingMapFile, options.remapfile, x.Message); } if(!loader.ValidateAndSetMap(map)) { return 1; } } finally { fs.Close(); } if(loader.CheckCompilingCoreAssembly()) { compilingCoreAssembly = true; ClassLoaderWrapper.SetBootstrapClassLoader(loader); } } // If we do not yet have a reference to the core assembly and we are not compiling the core assembly, // try to find the core assembly by looking at the assemblies that the runtime references if(JVM.CoreAssembly == null && !compilingCoreAssembly) { foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies()) { Assembly asm = null; try { asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll"); } catch(FileNotFoundException) { } if(asm != null && IsCoreAssembly(asm)) { AssemblyClassLoader.PreloadExportedAssemblies(asm); JVM.CoreAssembly = asm; break; } } if(JVM.CoreAssembly == null) { throw new FatalCompilerErrorException(Message.BootstrapClassesMissing); } // we need to scan again for remapped types, now that we've loaded the core library ClassLoaderWrapper.LoadRemappedTypes(); } if(!compilingCoreAssembly) { allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly)); } if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) { throw new FatalCompilerErrorException(Message.StrongNameRequiresStrongNamedRefs); } if(loader.map != null) { loader.LoadMapXml(); } if(!compilingCoreAssembly) { FakeTypes.Load(JVM.CoreAssembly); } return 0; }
public static global::java.lang.ClassLoader getAssemblyClassLoader(Assembly asm) { // note that we don't do a security check here, because if you have the Assembly object, // you can already get at all the types in it. return(AssemblyClassLoader_.FromAssembly(asm).GetJavaClassLoader()); }
internal void AddDelegate(AssemblyClassLoader acl) { LazyInitExports(); Array.Resize(ref delegates, delegates.Length + 1); delegates[delegates.Length - 1] = acl; }
private IEnumerable <java.net.URL> GetResourcesImpl(string unmangledName, bool getFromDelegates) { if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly)) { yield break; } #if !FIRST_PASS java.util.Enumeration urls = assemblyLoader.FindResources(unmangledName); while (urls.hasMoreElements()) { yield return((java.net.URL)urls.nextElement()); } #endif string name = JVM.MangleResourceName(unmangledName); if (assemblyLoader.Assembly.GetManifestResourceInfo(name) != null) { yield return(MakeResourceURL(assemblyLoader.Assembly, name)); } LazyInitExports(); if (exports != null) { List <int> assemblies; if (exports.TryGetValue(JVM.PersistableHash(unmangledName), out assemblies)) { foreach (int index in assemblies) { AssemblyLoader loader = exportedAssemblies[index]; if (loader == null) { Assembly asm = LoadAssemblyOrClearName(ref exportedAssemblyNames[index], true); if (asm == null) { continue; } loader = exportedAssemblies[index] = GetLoaderForExportedAssembly(asm); } #if !FIRST_PASS urls = loader.FindResources(unmangledName); while (urls.hasMoreElements()) { yield return((java.net.URL)urls.nextElement()); } #endif if (loader.Assembly.GetManifestResourceInfo(name) != null) { yield return(MakeResourceURL(loader.Assembly, name)); } } } } if (!getFromDelegates) { yield break; } for (int i = 0; i < delegates.Length; i++) { if (delegates[i] == null) { Assembly asm = LoadAssemblyOrClearName(ref references[i], false); if (asm != null) { delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) { foreach (java.net.URL url in delegates[i].FindResources(unmangledName)) { yield return(url); } } } if (!assemblyLoader.HasJavaModule) { foreach (java.net.URL url in GetBootstrapClassLoader().FindResources(unmangledName)) { yield return(url); } } }
internal Resource(java.net.URL url, AssemblyClassLoader loader) { this.URL = url; this.Loader = loader; }
internal void AddDelegate(AssemblyClassLoader acl) { LazyInitExports(); lock (this) { delegates = ArrayUtil.Concat(delegates, acl); } }
internal Assembly[] FindResourceAssemblies(string unmangledName, bool firstOnly) { List <Assembly> list = null; string name = JVM.MangleResourceName(unmangledName); Assembly first = FindResourceAssembliesImpl(unmangledName, name, firstOnly, ref list); if (first != null) { return(new Assembly[] { first }); } LazyInitExports(); for (int i = 0; i < delegates.Length; i++) { if (delegates[i] == null) { Assembly asm = LoadAssemblyOrClearName(ref references[i], false); if (asm != null) { delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) { first = delegates[i].FindResourceAssembliesImpl(unmangledName, name, firstOnly, ref list); if (first != null) { return(new Assembly[] { first }); } } } if (!assemblyLoader.HasJavaModule) { if (firstOnly) { return(GetBootstrapClassLoader().FindResourceAssemblies(unmangledName, firstOnly)); } else { Assembly[] assemblies = GetBootstrapClassLoader().FindResourceAssemblies(unmangledName, firstOnly); if (assemblies != null) { foreach (Assembly asm in assemblies) { if (list == null) { list = new List <Assembly>(); } if (!list.Contains(asm)) { list.Add(asm); } } } } } if (list == null) { return(null); } return(list.ToArray()); }
private void Populate() { bool populate; lock (entries) { populate = entries.Count == 0; } if (populate) { Dictionary <string, string> names = new Dictionary <string, string>(); AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(this.asm); foreach (Assembly asm in acl.GetAllAvailableAssemblies()) { Type[] types; try { types = asm.GetTypes(); } catch (ReflectionTypeLoadException x) { types = x.Types; } catch { types = Type.EmptyTypes; } foreach (Type type in types) { if (type != null) { string name = null; try { bool isJavaType; name = acl.GetTypeNameAndType(type, out isJavaType); #if !FIRST_PASS // annotation custom attributes are pseudo proxies and are not loadable by name (and should not exist in the file systems, // because proxies are, ostensibly, created on the fly) if (isJavaType && type.BaseType == typeof(global::[email protected]) && name.Contains(".$Proxy")) { name = null; } #endif } catch { } if (name != null) { names[name] = name; } } } } lock (entries) { if (entries.Count == 0) { foreach (string name in names.Keys) { string[] parts = name.Split('.'); VfsDirectory dir = this; for (int i = 0; i < parts.Length - 1; i++) { dir = dir.GetEntry(parts[i]) as VfsDirectory ?? dir.AddDirectory(parts[i]); } // we're adding a dummy file, to make the file appear in the directory listing, it will not actually // be accessed, because the code above handles that dir.Add(parts[parts.Length - 1] + ".class", VfsDummyFile.Instance); } } } } }
internal static TypeWrapper GetWrapperFromType(Type type) { //Tracer.Info(Tracer.Runtime, "GetWrapperFromType: {0}", type.AssemblyQualifiedName); #if !STATIC_COMPILER TypeWrapper.AssertFinished(type); #endif Debug.Assert(!type.IsPointer); Debug.Assert(!type.IsByRef); TypeWrapper wrapper; lock (globalTypeToTypeWrapper) { globalTypeToTypeWrapper.TryGetValue(type, out wrapper); } if (wrapper != null) { return(wrapper); } string remapped; if (remappedTypes.TryGetValue(type, out remapped)) { wrapper = LoadClassCritical(remapped); } else if (ReflectUtil.IsVector(type)) { // it might be an array of a dynamically compiled Java type int rank = 1; Type elem = type.GetElementType(); while (ReflectUtil.IsVector(elem)) { rank++; elem = elem.GetElementType(); } wrapper = GetWrapperFromType(elem).MakeArrayType(rank); } else { Assembly asm = type.Assembly; #if CLASSGC ClassLoaderWrapper loader; if (dynamicAssemblies != null && dynamicAssemblies.TryGetValue(asm, out loader)) { lock (loader.typeToTypeWrapper) { return(loader.typeToTypeWrapper[type]); } } #endif #if !STATIC_COMPILER && !STUB_GENERATOR if (ReflectUtil.IsReflectionOnly(type)) { // historically we've always returned null for types that don't have a corresponding TypeWrapper (or java.lang.Class) return(null); } #endif // if the wrapper doesn't already exist, that must mean that the type // is a .NET type (or a pre-compiled Java class), which means that it // was "loaded" by an assembly classloader wrapper = AssemblyClassLoader.FromAssembly(asm).GetWrapperFromAssemblyType(type); } #if CLASSGC if (type.Assembly.IsDynamic) { // don't cache types in dynamic assemblies, because they might live in a RunAndCollect assembly // TODO we also shouldn't cache generic type instances that have a GCable type parameter return(wrapper); } #endif lock (globalTypeToTypeWrapper) { globalTypeToTypeWrapper[type] = wrapper; } return(wrapper); }
internal void AddReference(AssemblyClassLoader acl) { AssemblyClassLoader[] temp = new AssemblyClassLoader[referencedAssemblies.Length + 1]; Array.Copy(referencedAssemblies, 0, temp, 0, referencedAssemblies.Length); temp[temp.Length - 1] = acl; referencedAssemblies = temp; }
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); AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName(); bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly); List<Assembly> references = new List<Assembly>(); foreach(Assembly reference in options.references ?? new Assembly[0]) { references.Add(reference); allReferencesAreStrongNamed &= IsSigned(reference); Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName); // if it's an IKVM compiled assembly, make sure that it was compiled // against same version of the runtime foreach(AssemblyName asmref in reference.GetReferencedAssemblies()) { if(asmref.Name == runtimeAssemblyName.Name) { if(IsSigned(StaticCompiler.runtimeAssembly)) { // TODO we really should support binding redirects here to allow different revisions to be mixed if(asmref.FullName != runtimeAssemblyName.FullName) { throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); } } else { if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0) { throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); } } } } } List<object> assemblyAnnotations = new List<object>(); Dictionary<string, string> baseClasses = new Dictionary<string, string>(); Tracer.Info(Tracer.Compiler, "Parsing class files"); foreach(KeyValuePair<string, ClassItem> kv in options.classes) { ClassFile f; try { byte[] buf = kv.Value.data; f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None); if(!f.IsInterface && f.SuperClass != null) { baseClasses[f.SuperClass] = f.SuperClass; } // NOTE the "assembly" type in the unnamed package is a magic type // that acts as the placeholder for assembly attributes if(f.Name == "assembly" && f.Annotations != null) { assemblyAnnotations.AddRange(f.Annotations); } } catch(ClassFormatError) { continue; } if(options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) { foreach(ClassFile.Method m in f.Methods) { if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); options.mainClass = f.Name; break; } } } } Dictionary<string, ClassItem> h = new Dictionary<string, ClassItem>(); // HACK remove "assembly" type that exists only as a placeholder for assembly attributes options.classes.Remove("assembly"); foreach(KeyValuePair<string, ClassItem> kv in options.classes) { string name = kv.Key; bool excluded = false; for(int j = 0; j < options.classesToExclude.Length; j++) { if(Regex.IsMatch(name, options.classesToExclude[j])) { excluded = true; break; } } if(h.ContainsKey(name)) { StaticCompiler.IssueMessage(Message.DuplicateClassName, name); excluded = true; } if(!excluded) { h[name] = kv.Value; } } options.classes = null; if(options.guessFileKind && options.mainClass == null) { options.target = PEFileKinds.Dll; } if(options.target == PEFileKinds.Dll && options.mainClass != null) { throw new FatalCompilerErrorException(Message.MainClassRequiresExe); } if(options.target != PEFileKinds.Dll && options.mainClass == null) { throw new FatalCompilerErrorException(Message.ExeRequiresMainClass); } if(options.target == PEFileKinds.Dll && options.props.Count != 0) { throw new FatalCompilerErrorException(Message.PropertiesRequireExe); } if(options.path == null) { if(options.target == PEFileKinds.Dll) { if(options.targetIsModule) { options.path = options.assembly + ".netmodule"; } else { options.path = options.assembly + ".dll"; } } else { options.path = options.assembly + ".exe"; } StaticCompiler.IssueMessage(Message.OutputFileIs, options.path); } if(options.targetIsModule) { if(options.classLoader != null) { throw new FatalCompilerErrorException(Message.ModuleCannotHaveClassLoader); } // TODO if we're overwriting a user specified assembly name, we need to emit a warning options.assembly = new FileInfo(options.path).Name; } Tracer.Info(Tracer.Compiler, "Constructing compiler"); AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count]; for(int i = 0; i < references.Count; i++) { AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]); if (acl.MainAssembly != references[i]) { StaticCompiler.IssueMessage(options, Message.NonPrimaryAssemblyReference, references[i].GetName().Name, acl.MainAssembly.GetName().Name); } if (Array.IndexOf(referencedAssemblies, acl) != -1) { StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName); } referencedAssemblies[i] = acl; } loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h); loader.baseClasses = baseClasses; loader.assemblyAnnotations = assemblyAnnotations; loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) { Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile); System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root)); ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement); ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute); FileStream fs; try { fs = File.OpenRead(options.remapfile); } catch(Exception x) { throw new FatalCompilerErrorException(Message.ErrorReadingFile, options.remapfile, x.Message); } try { XmlTextReader rdr = new XmlTextReader(fs); IKVM.Internal.MapXml.Root.xmlReader = rdr; IKVM.Internal.MapXml.Root map; try { map = (IKVM.Internal.MapXml.Root)ser.Deserialize(rdr); } catch(InvalidOperationException x) { throw new FatalCompilerErrorException(Message.ErrorParsingMapFile, options.remapfile, x.Message); } if(!loader.ValidateAndSetMap(map)) { return 1; } } finally { fs.Close(); } if(loader.CheckCompilingCoreAssembly()) { compilingCoreAssembly = true; ClassLoaderWrapper.SetBootstrapClassLoader(loader); } } // If we do not yet have a reference to the core assembly and we are not compiling the core assembly, // try to find the core assembly by looking at the assemblies that the runtime references if(JVM.CoreAssembly == null && !compilingCoreAssembly) { foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies()) { Assembly asm = null; try { asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll"); } catch(FileNotFoundException) { } if(asm != null && IsCoreAssembly(asm)) { JVM.CoreAssembly = asm; break; } } if(JVM.CoreAssembly == null) { throw new FatalCompilerErrorException(Message.BootstrapClassesMissing); } // we need to scan again for remapped types, now that we've loaded the core library ClassLoaderWrapper.LoadRemappedTypes(); } if(!compilingCoreAssembly) { allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly)); } if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) { throw new FatalCompilerErrorException(Message.StrongNameRequiresStrongNamedRefs); } if(loader.map != null) { loader.LoadMapXml(); } if(!compilingCoreAssembly) { FakeTypes.Load(JVM.CoreAssembly); } return 0; }
internal void AddReference(AssemblyClassLoader acl) { referencedAssemblies = ArrayUtil.Concat(referencedAssemblies, acl); }
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); AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName(); bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly); List<Assembly> references = new List<Assembly>(); foreach(Assembly reference in options.references ?? new Assembly[0]) { try { if(IsCoreAssembly(reference)) { JVM.CoreAssembly = reference; } references.Add(reference); allReferencesAreStrongNamed &= IsSigned(reference); Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName); // if it's an IKVM compiled assembly, make sure that it was compiled // against same version of the runtime foreach(AssemblyName asmref in reference.GetReferencedAssemblies()) { if(asmref.Name == runtimeAssemblyName.Name) { if(IsSigned(StaticCompiler.runtimeAssembly)) { if(asmref.FullName != runtimeAssemblyName.FullName) { Console.Error.WriteLine("Error: referenced assembly {0} was compiled with an incompatible IKVM.Runtime version ({1})", reference.Location, asmref.Version); Console.Error.WriteLine(" Current runtime: {0}", runtimeAssemblyName.FullName); Console.Error.WriteLine(" Referenced assembly runtime: {0}", asmref.FullName); return 1; } } else { if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0) { Console.Error.WriteLine("Error: referenced assembly {0} was compiled with an incompatible (signed) IKVM.Runtime version", reference.Location); Console.Error.WriteLine(" Current runtime: {0}", runtimeAssemblyName.FullName); Console.Error.WriteLine(" Referenced assembly runtime: {0}", asmref.FullName); return 1; } } } } } catch(Exception x) { Console.Error.WriteLine("Error: invalid reference: {0} ({1})", reference.Location, x.Message); return 1; } } List<object> assemblyAnnotations = new List<object>(); Dictionary<string, string> baseClasses = new Dictionary<string, string>(); Tracer.Info(Tracer.Compiler, "Parsing class files"); foreach(KeyValuePair<string, byte[]> kv in options.classes) { ClassFile f; try { byte[] buf = kv.Value; f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None); if(!f.IsInterface && f.SuperClass != null) { baseClasses[f.SuperClass] = f.SuperClass; } // NOTE the "assembly" type in the unnamed package is a magic type // that acts as the placeholder for assembly attributes if(f.Name == "assembly" && f.Annotations != null) { assemblyAnnotations.AddRange(f.Annotations); } } catch(ClassFormatError) { continue; } if(options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) { foreach(ClassFile.Method m in f.Methods) { if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); options.mainClass = f.Name; break; } } } } Dictionary<string, byte[]> h = new Dictionary<string, byte[]>(); // HACK remove "assembly" type that exists only as a placeholder for assembly attributes options.classes.Remove("assembly"); foreach(KeyValuePair<string, byte[]> kv in options.classes) { string name = kv.Key; bool excluded = false; for(int j = 0; j < options.classesToExclude.Length; j++) { if(Regex.IsMatch(name, options.classesToExclude[j])) { excluded = true; break; } } if(h.ContainsKey(name)) { StaticCompiler.IssueMessage(Message.DuplicateClassName, name); excluded = true; } if(!excluded) { h[name] = kv.Value; } } options.classes = null; if(options.guessFileKind && options.mainClass == null) { options.target = PEFileKinds.Dll; } if(options.target == PEFileKinds.Dll && options.mainClass != null) { Console.Error.WriteLine("Error: main class cannot be specified for library or module"); return 1; } if(options.target != PEFileKinds.Dll && options.mainClass == null) { Console.Error.WriteLine("Error: no main method found"); return 1; } if(options.target == PEFileKinds.Dll && options.props.Count != 0) { Console.Error.WriteLine("Error: properties cannot be specified for library or module"); return 1; } if(options.path == null) { if(options.target == PEFileKinds.Dll) { if(options.targetIsModule) { options.path = options.assembly + ".netmodule"; } else { options.path = options.assembly + ".dll"; } } else { options.path = options.assembly + ".exe"; } StaticCompiler.IssueMessage(Message.OutputFileIs, options.path); } if(options.targetIsModule) { if(options.classLoader != null) { Console.Error.WriteLine("Error: cannot specify assembly class loader for modules"); return 1; } // TODO if we're overwriting a user specified assembly name, we need to emit a warning options.assembly = new FileInfo(options.path).Name; } if(options.target == PEFileKinds.Dll && !options.path.ToLower().EndsWith(".dll") && !options.targetIsModule) { Console.Error.WriteLine("Error: library output file must end with .dll"); return 1; } if(options.target != PEFileKinds.Dll && !options.path.ToLower().EndsWith(".exe")) { Console.Error.WriteLine("Error: executable output file must end with .exe"); return 1; } Tracer.Info(Tracer.Compiler, "Constructing compiler"); AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count]; for(int i = 0; i < references.Count; i++) { referencedAssemblies[i] = AssemblyClassLoader.FromAssembly(references[i]); } loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h); loader.baseClasses = baseClasses; loader.assemblyAnnotations = assemblyAnnotations; loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) { Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile); System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root)); ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement); ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute); using(FileStream fs = File.Open(options.remapfile, FileMode.Open)) { XmlTextReader rdr = new XmlTextReader(fs); IKVM.Internal.MapXml.Root.xmlReader = rdr; IKVM.Internal.MapXml.Root.filename = new FileInfo(fs.Name).Name; if (!loader.ValidateAndSetMap((IKVM.Internal.MapXml.Root)ser.Deserialize(rdr))) { return 1; } } if(loader.CheckCompilingCoreAssembly()) { compilingCoreAssembly = true; ClassLoaderWrapper.SetBootstrapClassLoader(loader); loader.EmitRemappedTypes(); } } // If we do not yet have a reference to the core assembly and we are not compiling the core assembly, // try to find the core assembly by looking at the assemblies that the runtime references if(JVM.CoreAssembly == null && !compilingCoreAssembly) { foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies()) { Assembly asm = null; try { asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll"); } catch(FileNotFoundException) { } if(asm != null && IsCoreAssembly(asm)) { JVM.CoreAssembly = asm; break; } } if(JVM.CoreAssembly == null) { Console.Error.WriteLine("Error: bootstrap classes missing and core assembly not found"); return 1; } // we need to scan again for remapped types, now that we've loaded the core library ClassLoaderWrapper.LoadRemappedTypes(); } if(!compilingCoreAssembly) { allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly)); } if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) { Console.Error.WriteLine("Error: all referenced assemblies must be strong named, to be able to sign the output assembly"); return 1; } if(loader.map != null) { loader.LoadMapXml(); } if(!compilingCoreAssembly) { FakeTypes.Load(JVM.CoreAssembly); } return 0; }