IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
Class.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2007-2014 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Collections.Generic;
26
27using IKVM.Runtime;
29
31{
32
36 static class Class
37 {
38
39#if FIRST_PASS == false
40
41 static ClassLoaderAccessor classLoaderAccessor;
42
43 static ClassLoaderAccessor ClassLoaderAccessor => JVM.Internal.BaseAccessors.Get(ref classLoaderAccessor);
44
45#endif
46
57 public static global::java.lang.Class forName0(string name, bool initialize, global::java.lang.ClassLoader loader, global::java.lang.Class caller)
58 {
59#if FIRST_PASS
60 throw new NotImplementedException();
61#else
62 if (name == null)
63 throw new global::java.lang.NullPointerException();
64
65 RuntimeJavaType javaType = null;
66 if (name.IndexOf(',') > 0)
67 {
68 // we essentially require full trust before allowing arbitrary types to be loaded,
69 // hence we do the "createClassLoader" permission check
70 var sm = global::java.lang.System.getSecurityManager();
71 sm?.checkPermission(new global::java.lang.RuntimePermission("createClassLoader"));
72
73 var type = Type.GetType(name);
74 if (type != null)
75 javaType = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type);
76
77 if (javaType == null)
78 {
79 global::java.lang.Throwable.suppressFillInStackTrace = true;
80 throw new global::java.lang.ClassNotFoundException(name);
81 }
82 }
83 else
84 {
85 try
86 {
87 javaType = JVM.Context.ClassLoaderFactory.GetClassLoaderWrapper(loader).LoadClassByName(name);
88 }
90 {
91 global::java.lang.Throwable.suppressFillInStackTrace = true;
92 throw new global::java.lang.ClassNotFoundException(e.Message);
93 }
94 catch (ClassLoadingException e)
95 {
96 throw e.InnerException;
97 }
99 {
100 throw e.ToJava();
101 }
102 }
103
104 if (loader != null && caller != null && getProtectionDomain0(caller) is global::java.security.ProtectionDomain pd)
105 ClassLoaderAccessor.InvokeCheckPackageAccess(loader, javaType.ClassObject, pd);
106
107 if (initialize && javaType.IsArray == false)
108 {
109 try
110 {
111 javaType.Finish();
112 }
114 {
115 throw e.ToJava();
116 }
117
118 javaType.RunClassInit();
119 }
120
121 return javaType.ClassObject;
122#endif
123 }
124
130 public static byte[] getRawTypeAnnotations(global::java.lang.Class thisClass)
131 {
132 return RuntimeJavaType.FromClass(thisClass).GetRawTypeAnnotations();
133 }
134
135#if !FIRST_PASS
136
137 sealed class ConstantPoolImpl : global::sun.reflect.ConstantPool
138 {
139
140 readonly object[] constantPool;
141
146 internal ConstantPoolImpl(object[] constantPool)
147 {
148 this.constantPool = constantPool;
149 }
150
151 public override string getUTF8At(int index)
152 {
153 return (string)constantPool[index];
154 }
155
156 public override int getIntAt(int index)
157 {
158 return (int)constantPool[index];
159 }
160
161 public override long getLongAt(int index)
162 {
163 return (long)constantPool[index];
164 }
165
166 public override float getFloatAt(int index)
167 {
168 return (float)constantPool[index];
169 }
170
171 public override double getDoubleAt(int index)
172 {
173 return (double)constantPool[index];
174 }
175 }
176
177#endif
178
184 public static object getConstantPool(global::java.lang.Class self)
185 {
186#if FIRST_PASS
187 throw new NotImplementedException();
188#else
189 return new ConstantPoolImpl(RuntimeJavaType.FromClass(self).GetConstantPool());
190#endif
191 }
192
199 public static bool isInstance(global::java.lang.Class self, object obj)
200 {
201 return RuntimeJavaType.FromClass(self).IsInstance(obj);
202 }
203
211 public static bool isAssignableFrom(global::java.lang.Class self, global::java.lang.Class otherClass)
212 {
213#if FIRST_PASS
214 throw new NotImplementedException();
215#else
216 if (otherClass == null)
217 throw new global::java.lang.NullPointerException();
218
219 return RuntimeJavaType.FromClass(otherClass).IsAssignableTo(RuntimeJavaType.FromClass(self));
220#endif
221 }
222
228 public static bool isInterface(global::java.lang.Class self)
229 {
230 return RuntimeJavaType.FromClass(self).IsInterface;
231 }
232
233 public static bool isArray(global::java.lang.Class thisClass)
234 {
235 return RuntimeJavaType.FromClass(thisClass).IsArray;
236 }
237
238 public static bool isPrimitive(global::java.lang.Class thisClass)
239 {
240 return RuntimeJavaType.FromClass(thisClass).IsPrimitive;
241 }
242
243 public static string getName0(global::java.lang.Class thisClass)
244 {
245#if FIRST_PASS
246 throw new NotImplementedException();
247#else
248 var type = RuntimeJavaType.FromClass(thisClass);
249 if (type.IsPrimitive)
250 {
251 if (type == JVM.Context.PrimitiveJavaTypeFactory.BYTE)
252 return "byte";
253 else if (type == JVM.Context.PrimitiveJavaTypeFactory.CHAR)
254 return "char";
255 else if (type == JVM.Context.PrimitiveJavaTypeFactory.DOUBLE)
256 return "double";
257 else if (type == JVM.Context.PrimitiveJavaTypeFactory.FLOAT)
258 return "float";
259 else if (type == JVM.Context.PrimitiveJavaTypeFactory.INT)
260 return "int";
261 else if (type == JVM.Context.PrimitiveJavaTypeFactory.LONG)
262 return "long";
263 else if (type == JVM.Context.PrimitiveJavaTypeFactory.SHORT)
264 return "short";
265 else if (type == JVM.Context.PrimitiveJavaTypeFactory.BOOLEAN)
266 return "boolean";
267 else if (type == JVM.Context.PrimitiveJavaTypeFactory.VOID)
268 return "void";
269 }
270
271 if (type.IsUnsafeAnonymous)
272 {
273 // for OpenJDK compatibility and debugging convenience we modify the class name to
274 // include the identity hashcode of the class object
275 return type.Name + "/" + global::java.lang.System.identityHashCode(thisClass);
276 }
277
278 return type.Name;
279#endif
280 }
281
282 public static string getSigName(global::java.lang.Class thisClass)
283 {
284 return RuntimeJavaType.FromClass(thisClass).SigName;
285 }
286
287 public static global::java.lang.ClassLoader getClassLoader0(global::java.lang.Class thisClass)
288 {
289 return RuntimeJavaType.FromClass(thisClass).ClassLoader.GetJavaClassLoader();
290 }
291
292 public static global::java.lang.Class getSuperclass(global::java.lang.Class thisClass)
293 {
294 return RuntimeJavaType.FromClass(thisClass).BaseTypeWrapper?.ClassObject;
295 }
296
297 public static global::java.lang.Class[] getInterfaces0(global::java.lang.Class thisClass)
298 {
299#if FIRST_PASS
300 throw new NotImplementedException();
301#else
302 var ifaces = RuntimeJavaType.FromClass(thisClass).Interfaces;
303 var interfaces = new global::java.lang.Class[ifaces.Length];
304 for (int i = 0; i < ifaces.Length; i++)
305 interfaces[i] = ifaces[i].ClassObject;
306
307 return interfaces;
308#endif
309 }
310
311 public static global::java.lang.Class getComponentType(global::java.lang.Class thisClass)
312 {
313 var type = RuntimeJavaType.FromClass(thisClass);
314 return type.IsArray ? type.ElementTypeWrapper.ClassObject : null;
315 }
316
317 public static int getModifiers(global::java.lang.Class thisClass)
318 {
319 // the 0x7FFF mask comes from JVM_ACC_WRITTEN_FLAGS in hotspot\src\share\vm\utilities\accessFlags.hpp
320 // masking out ACC_SUPER comes from instanceKlass::compute_modifier_flags() in hotspot\src\share\vm\oops\instanceKlass.cpp
321 const int mask = 0x7FFF & (int)~IKVM.Attributes.Modifiers.Super;
322 return (int)RuntimeJavaType.FromClass(thisClass).ReflectiveModifiers & mask;
323 }
324
325 public static object[] getSigners(global::java.lang.Class thisClass)
326 {
327#if FIRST_PASS
328 throw new NotImplementedException();
329#else
330 return thisClass.signers;
331#endif
332 }
333
334 public static void setSigners(global::java.lang.Class thisClass, object[] signers)
335 {
336#if !FIRST_PASS
337 thisClass.signers = signers;
338#endif
339 }
340
341 public static object[] getEnclosingMethod0(global::java.lang.Class thisClass)
342 {
343 try
344 {
345 var type = RuntimeJavaType.FromClass(thisClass);
346 type.Finish();
347
348 var enc = type.GetEnclosingMethod();
349 if (enc == null)
350 return null;
351
352 return [type.ClassLoader.LoadClassByName(enc[0]).ClassObject, enc[1], enc[2]?.Replace('.', '/')];
353 }
355 {
356 throw x.ToJava();
357 }
358 }
359
360 public static global::java.lang.Class getDeclaringClass0(global::java.lang.Class thisClass)
361 {
362 try
363 {
364 var type = RuntimeJavaType.FromClass(thisClass);
365 type.Finish();
366
367 var declaringType = type.DeclaringTypeWrapper;
368 if (declaringType == null)
369 return null;
370
371 declaringType = declaringType.EnsureLoadable(type.ClassLoader);
372 if (declaringType.IsAccessibleFrom(type) == false)
373 throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", declaringType.Name, type.Name));
374
375 declaringType.Finish();
376
377 foreach (var declaringTypeInnerType in declaringType.InnerClasses)
378 if (declaringTypeInnerType.Name == type.Name && declaringTypeInnerType.EnsureLoadable(declaringType.ClassLoader) == type)
379 return declaringType.ClassObject;
380
381 throw new IncompatibleClassChangeError(string.Format("{0} and {1} disagree on InnerClasses attribute", declaringType.Name, type.Name));
382 }
384 {
385 throw x.ToJava();
386 }
387 }
388
389 public static global::java.security.ProtectionDomain getProtectionDomain0(global::java.lang.Class thisClass)
390 {
391#if FIRST_PASS
392 throw new NotImplementedException();
393#else
394 var type = RuntimeJavaType.FromClass(thisClass);
395 if (type.IsArray)
396 return null;
397
398 var pd = type.ClassObject.pd;
399 if (pd == null)
400 {
401 // The protection domain for statically compiled code is created lazily (not at global::java.lang.Class creation time),
402 // to work around boot strap issues.
403 if (type.ClassLoader is RuntimeAssemblyClassLoader acl)
404 {
405 pd = acl.GetProtectionDomain();
406 }
407 else if (type is RuntimeAnonymousJavaType)
408 {
409 // dynamically compiled intrinsified lamdba anonymous types end up here and should get their
410 // protection domain from the host class
411 pd = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type.TypeAsTBD.DeclaringType).ClassObject.pd;
412 }
413 }
414
415 return pd;
416#endif
417 }
418
429 public static global::java.lang.Class getPrimitiveClass(string name)
430 {
431#if FIRST_PASS
432 throw new NotImplementedException();
433#else
434 return name switch
435 {
436 "byte" => JVM.Context.PrimitiveJavaTypeFactory.BYTE.ClassObject,
437 "char" => JVM.Context.PrimitiveJavaTypeFactory.CHAR.ClassObject,
438 "double" => JVM.Context.PrimitiveJavaTypeFactory.DOUBLE.ClassObject,
439 "float" => JVM.Context.PrimitiveJavaTypeFactory.FLOAT.ClassObject,
440 "int" => JVM.Context.PrimitiveJavaTypeFactory.INT.ClassObject,
441 "long" => JVM.Context.PrimitiveJavaTypeFactory.LONG.ClassObject,
442 "short" => JVM.Context.PrimitiveJavaTypeFactory.SHORT.ClassObject,
443 "boolean" => JVM.Context.PrimitiveJavaTypeFactory.BOOLEAN.ClassObject,
444 "void" => JVM.Context.PrimitiveJavaTypeFactory.VOID.ClassObject,
445 _ => throw new ArgumentException(name),
446 };
447#endif
448 }
449
450 public static string getGenericSignature0(global::java.lang.Class thisClass)
451 {
452 var type = RuntimeJavaType.FromClass(thisClass);
453 type.Finish();
454 return type.GetGenericSignature();
455 }
456
457 internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] objAnn)
458 {
459#if FIRST_PASS
460 throw new NotImplementedException();
461#else
462 var map = new global::java.util.LinkedHashMap();
463 if (objAnn != null)
464 {
465 foreach (object obj in objAnn)
466 {
467 var a = obj as global::java.lang.annotation.Annotation;
468 if (a != null)
469 {
470 map.put(a.annotationType(), FreezeOrWrapAttribute(a));
471 }
473 {
474 a = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(loader.GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition);
475 if (a != null)
476 map.put(a.annotationType(), a);
477 }
478 }
479 }
480
481 return map;
482#endif
483 }
484
485#if !FIRST_PASS
486
487 internal static global::java.lang.annotation.Annotation FreezeOrWrapAttribute(global::java.lang.annotation.Annotation ann)
488 {
489 var attr = ann as global::ikvm.@internal.AnnotationAttributeBase;
490 if (attr != null)
491 {
492#if DONT_WRAP_ANNOTATION_ATTRIBUTES
493 attr.freeze();
494#else
495 // freeze to make sure the defaults are set
496 attr.freeze();
497 ann = global::sun.reflect.annotation.AnnotationParser.annotationForMap(attr.annotationType(), attr.getValues());
498#endif
499 }
500 return ann;
501 }
502#endif
503
504 public static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClass)
505 {
506#if FIRST_PASS
507 throw new NotImplementedException();
508#else
509 var type = RuntimeJavaType.FromClass(thisClass);
510
511 try
512 {
513 type.Finish();
514 }
516 {
517 throw x.ToJava();
518 }
519
520 return AnnotationsToMap(type.ClassLoader, type.GetDeclaredAnnotations());
521#endif
522 }
523
524 public static object getDeclaredFields0(global::java.lang.Class thisClass, bool publicOnly)
525 {
526#if FIRST_PASS
527 throw new NotImplementedException();
528#else
529 try
530 {
531 var type = RuntimeJavaType.FromClass(thisClass);
532 type.Finish();
533
534 var fields = type.GetFields();
535 var list = new List<global::java.lang.reflect.Field>(fields.Length);
536
537 for (int i = 0; i < fields.Length; i++)
538 {
539 if (fields[i].IsHideFromReflection)
540 {
541 // skip
542 }
543 else if (publicOnly && !fields[i].IsPublic)
544 {
545 // caller is only asking for public field, so we don't return this non-public field
546 }
547 else
548 {
549 list.Add((global::java.lang.reflect.Field)fields[i].ToField(false, i));
550 }
551 }
552
553 return list.ToArray();
554 }
556 {
557 throw x.ToJava();
558 }
559#endif
560 }
561
562 public static object getDeclaredMethods0(global::java.lang.Class thisClass, bool publicOnly)
563 {
564#if FIRST_PASS
565 throw new NotImplementedException();
566#else
567 try
568 {
569 var type = RuntimeJavaType.FromClass(thisClass);
570 type.Finish();
571
572 if (type.HasVerifyError)
573 throw new VerifyError();
574
575 if (type.HasClassFormatError)
576 throw new ClassFormatError(type.Name);
577
578 var methods = type.GetMethods();
579 var list = new List<global::java.lang.reflect.Method>(methods.Length);
580 foreach (var method in methods)
581 {
582 // we don't want to expose "hideFromReflection" methods (one reason is that it would mess up the serialVersionUID computation)
583 if (!method.IsHideFromReflection && !method.IsConstructor && !method.IsClassInitializer && (!publicOnly || method.IsPublic))
584 list.Add((global::java.lang.reflect.Method)method.ToMethodOrConstructor(false));
585 }
586
587 return list.ToArray();
588 }
590 {
591 throw x.ToJava();
592 }
593#endif
594 }
595
596 public static object getDeclaredConstructors0(global::java.lang.Class thisClass, bool publicOnly)
597 {
598#if FIRST_PASS
599 throw new NotImplementedException();
600#else
601 try
602 {
603 var type = RuntimeJavaType.FromClass(thisClass);
604 type.Finish();
605
606 if (type.HasVerifyError)
607 throw new VerifyError();
608
609 if (type.HasClassFormatError)
610 throw new ClassFormatError(type.Name);
611
612 var methods = type.GetMethods();
613 var list = new List<global::java.lang.reflect.Constructor>(methods.Length);
614 foreach (var method in methods)
615 {
616 // we don't want to expose "hideFromReflection" methods (one reason is that it would mess up the serialVersionUID computation)
617 if (method.IsHideFromReflection == false && method.IsConstructor)
618 if (publicOnly == false || method.IsPublic)
619 list.Add((global::java.lang.reflect.Constructor)method.ToMethodOrConstructor(false));
620 }
621
622 return list.ToArray();
623 }
625 {
626 throw x.ToJava();
627 }
628#endif
629 }
630
631 public static global::java.lang.Class[] getDeclaredClasses0(global::java.lang.Class thisClass)
632 {
633#if FIRST_PASS
634 throw new NotImplementedException();
635#else
636 try
637 {
638 var type = RuntimeJavaType.FromClass(thisClass);
639 type.Finish();
640
641 var innerTypes = type.InnerClasses;
642 var list = new global::java.lang.Class[innerTypes.Length];
643 for (int i = 0; i < list.Length; i++)
644 {
645 var innerType = innerTypes[i].EnsureLoadable(type.ClassLoader);
646 if (innerType.IsAccessibleFrom(type) == false)
647 throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", innerType.Name, type.Name));
648
649 innerType.Finish();
650 list[i] = innerType.ClassObject;
651 }
652
653 return list;
654 }
656 {
657 throw x.ToJava();
658 }
659#endif
660 }
661
662 public static bool desiredAssertionStatus0(global::java.lang.Class clazz)
663 {
664 return IKVM.Runtime.Assertions.IsEnabled(RuntimeJavaType.FromClass(clazz));
665 }
666
667 }
668
669}
IKVM.Reflection.Type Type
Implements the native methods for 'java.lang.Class'.
Definition Class.cs:37
static object getDeclaredConstructors0(global::java.lang.Class thisClass, bool publicOnly)
Definition Class.cs:596
static global::java.lang.Class forName0(string name, bool initialize, global::java.lang.ClassLoader loader, global::java.lang.Class caller)
Implements the native method 'forName0'.
Definition Class.cs:57
static global::java.lang.Class getPrimitiveClass(string name)
Implements the native method for 'getPrimitiveClass'.
Definition Class.cs:429
static global::java.lang.Class[] getInterfaces0(global::java.lang.Class thisClass)
Definition Class.cs:297
static object getDeclaredFields0(global::java.lang.Class thisClass, bool publicOnly)
Definition Class.cs:524
static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClass)
Definition Class.cs:504
static global::java.security.ProtectionDomain getProtectionDomain0(global::java.lang.Class thisClass)
Definition Class.cs:389
static global::java.lang.Class[] getDeclaredClasses0(global::java.lang.Class thisClass)
Definition Class.cs:631
static bool isArray(global::java.lang.Class thisClass)
Definition Class.cs:233
static object getConstantPool(global::java.lang.Class self)
Implements the native method 'getConstantPool'.
Definition Class.cs:184
static int getModifiers(global::java.lang.Class thisClass)
Definition Class.cs:317
static global::java.lang.Class getComponentType(global::java.lang.Class thisClass)
Definition Class.cs:311
static object[] getEnclosingMethod0(global::java.lang.Class thisClass)
Definition Class.cs:341
static byte[] getRawTypeAnnotations(global::java.lang.Class thisClass)
Implements the native method 'getRawTypeAnnotations'.
Definition Class.cs:130
static bool isInstance(global::java.lang.Class self, object obj)
Implements the native method 'isInstance'.
Definition Class.cs:199
static void setSigners(global::java.lang.Class thisClass, object[] signers)
Definition Class.cs:334
static object getDeclaredMethods0(global::java.lang.Class thisClass, bool publicOnly)
Definition Class.cs:562
static string getName0(global::java.lang.Class thisClass)
Definition Class.cs:243
static global::java.lang.ClassLoader getClassLoader0(global::java.lang.Class thisClass)
Definition Class.cs:287
static bool isAssignableFrom(global::java.lang.Class self, global::java.lang.Class otherClass)
Implements the native method 'isAssignableFrom'.
Definition Class.cs:211
static string getGenericSignature0(global::java.lang.Class thisClass)
Definition Class.cs:450
static global::java.lang.Class getSuperclass(global::java.lang.Class thisClass)
Definition Class.cs:292
static object[] getSigners(global::java.lang.Class thisClass)
Definition Class.cs:325
static bool isPrimitive(global::java.lang.Class thisClass)
Definition Class.cs:238
static bool isInterface(global::java.lang.Class self)
Implements the native method 'isInterface'.
Definition Class.cs:228
static global::java.lang.Class getDeclaringClass0(global::java.lang.Class thisClass)
Definition Class.cs:360
static bool desiredAssertionStatus0(global::java.lang.Class clazz)
Definition Class.cs:662
static string getSigName(global::java.lang.Class thisClass)
Definition Class.cs:282
This is not a Java exception, but instead it wraps a Java exception that was thrown by a class loader...
Main state of the running JVM.
.NET exception that corresponds to a Java exception.
Represents an intrinsified anonymous class. Currently only used by LambdaMetafactory.
Runtime support for a class loader.
RuntimePrimitiveJavaTypeFactory PrimitiveJavaTypeFactory
Gets the RuntimePrimitiveJavaTypeFactory associated with this instance of the runtime.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.