delay jni init til the firt NewGlobalRef call
[cacao.git] / nat / VMClassLoader.c
1 /* nat/VMClassLoader.c - java/lang/ClassLoader
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30
31    $Id: VMClassLoader.c 1447 2004-11-05 14:00:22Z twisti $
32
33 */
34
35
36 #include "exceptions.h"
37 #include "jni.h"
38 #include "loader.h"
39 #include "native.h"
40 #include "builtin.h"
41 #include "tables.h"
42 #include "toolbox/logging.h"
43 #include "nat/java_lang_Class.h"
44 #include "nat/java_lang_String.h"
45 #include "nat/java_lang_ClassLoader.h"
46 #include "nat/java_net_URL.h"
47
48
49 /*
50  * Class:     java/lang/ClassLoader
51  * Method:    defineClass
52  * Signature: (Ljava/lang/String;[BII)Ljava/lang/Class;
53  */
54 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *this, java_lang_String *name, java_bytearray *buf, s4 off, s4 len)
55 {
56         classinfo *c;
57
58         log_text("Java_java_lang_VMClassLoader_defineClass called");
59
60         if (off < 0 || len < 0 || off + len > buf->header.size) {
61                 *exceptionptr =
62                         new_exception(string_java_lang_IndexOutOfBoundsException);
63                 return NULL;
64         }
65
66         /* call JNI-function to load the class */
67         c = (*env)->DefineClass(env,
68                                                         javastring_tochar((java_objectheader *) name),
69                                                         (jobject) this,
70                                                         (const jbyte *) &buf->data[off],
71                                                         len);
72
73         /* exception? return! */
74         if (!c)
75                 return NULL;
76
77         use_class_as_object(c);
78
79         return (java_lang_Class *) c;
80 }
81
82
83 /*
84  * Class:     java/lang/ClassLoader
85  * Method:    getPrimitiveClass
86  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
87  */
88 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, java_lang_String *name)
89 {
90         classinfo *c;
91         utf *u = javastring_toutf(name, false);
92
93         /* illegal primitive classname specified */
94         if (!u) {
95                 *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
96                 return NULL;
97         }
98
99         /* get primitive class */
100         c = class_new(u);
101
102         if (!class_load(c))
103                 return NULL;
104
105         if (!class_init(c))
106                 return NULL;
107
108         use_class_as_object(c);
109
110         return (java_lang_Class *) c;
111 }
112
113
114 /*
115  * Class:     java/lang/ClassLoader
116  * Method:    resolveClass
117  * Signature: (Ljava/lang/Class;)V
118  */
119 JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
120 {
121         classinfo *ci;
122
123         ci = (classinfo *) c;
124
125         if (!ci) {
126                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
127                 return;
128         }
129
130         /* link the class */
131         if (!ci->linked)
132                 class_link(ci);
133
134         return;
135 }
136
137
138 /*
139  * Class:     java/lang/VMClassLoader
140  * Method:    loadClass
141  * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
142  */
143 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
144 {
145         classinfo *c;
146         utf *u;
147
148         if (!name) {
149                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
150                 return NULL;
151         }
152
153         /* create utf string in which '.' is replaced by '/' */
154         u = javastring_toutf(name, true);
155
156         /* create class */
157         c = class_new(u);
158
159         /* load class */
160         if (!class_load(c)) {
161                 classinfo *xclass;
162
163                 xclass = (*exceptionptr)->vftbl->class;
164
165                 /* if the exception is a NoClassDefFoundError, we replace it with a
166                    ClassNotFoundException, otherwise return the exception */
167
168                 if (xclass == class_get(utf_new_char(string_java_lang_NoClassDefFoundError))) {
169                         /* clear exceptionptr, because builtin_new checks for 
170                            ExceptionInInitializerError */
171                         *exceptionptr = NULL;
172
173                         *exceptionptr =
174                                 new_exception_javastring(string_java_lang_ClassNotFoundException, name);
175                 }
176
177                 return NULL;
178         }
179
180         /* resolve class -- if requested */
181         /* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
182 /*      if (resolve) */
183                 if (!class_link(c))
184                         return NULL;
185
186         use_class_as_object(c);
187
188         return (java_lang_Class *) c;
189 }
190
191
192 /*
193  * These are local overrides for various environment variables in Emacs.
194  * Please do not remove this and leave it at the end of the file, where
195  * Emacs will automagically detect them.
196  * ---------------------------------------------------------------------
197  * Local variables:
198  * mode: c
199  * indent-tabs-mode: t
200  * c-basic-offset: 4
201  * tab-width: 4
202  * End:
203  */