1 // natVMClassLoader.cc - VMClassLoader native methods
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 /* Author: Kresten Krab Thorup <krab@gnu.org> */
21 #include <java-threads.h>
22 #include <java-interp.h>
24 #include <java/lang/VMClassLoader.h>
25 #include <java/lang/VMCompiler.h>
26 #include <gnu/gcj/runtime/ExtensionClassLoader.h>
27 #include <gnu/gcj/runtime/SystemClassLoader.h>
28 #include <gnu/gcj/runtime/BootClassLoader.h>
29 #include <java/lang/ClassLoader.h>
30 #include <java/lang/Class.h>
31 #include <java/lang/Throwable.h>
32 #include <java/security/ProtectionDomain.h>
33 #include <java/lang/ClassFormatError.h>
34 #include <java/lang/StringBuffer.h>
35 #include <java/lang/Runtime.h>
36 #include <java/util/HashSet.h>
37 #include <java/lang/VirtualMachineError.h>
40 java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
45 java::security::ProtectionDomain *pd)
47 jclass klass = VMCompiler::compileClass(loader, name, data,
53 klass = new java::lang::Class ();
55 // Synchronize on the class, so that it is not attempted initialized
56 // until we're done loading.
57 JvSynchronize sync (klass);
59 // Record the defining loader. For the bootstrap class loader,
61 if (loader != bootLoader)
62 klass->loader = loader;
66 _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
68 if (! _Jv_VerifyClassName (name2))
69 throw new java::lang::ClassFormatError
70 (JvNewStringLatin1 ("erroneous class name"));
75 _Jv_Utf8Const *found_name = NULL;
78 _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
80 catch (java::lang::Throwable *ex)
82 klass->state = JV_STATE_ERROR;
85 if (found_name != NULL)
86 _Jv_UnregisterInitiatingLoader (klass, klass->loader);
88 // If EX is not a ClassNotFoundException, that's ok, because we
89 // account for the possibility in defineClass().
93 // if everything proceeded sucessfully, we're loaded.
94 JvAssert (klass->state == JV_STATE_LOADED);
100 StringBuffer *sb = new StringBuffer();
103 sb->append(JvNewStringLatin1("found class file for class "));
107 sb->append(JvNewStringLatin1("found unnamed class file"));
108 sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
109 throw new VirtualMachineError(sb->toString());
115 java::lang::ClassLoader *
116 java::lang::VMClassLoader::getSystemClassLoaderInternal()
118 _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
119 _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
120 return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
124 java::lang::VMClassLoader::getPrimitiveClass (jchar type)
127 sig[0] = (char) type;
129 // Note: this cannot return NULL, since the input is always correct.
130 return _Jv_FindClassFromSignature (sig, NULL);
134 java::lang::VMClassLoader::initBootLoader(jstring libdir)
136 bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
140 java::lang::VMClassLoader::nativeFindClass (jstring name)
144 if (lib_control != LIB_NEVER)
146 // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
147 // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
148 // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
149 // these causes the class to appear in the cache, then use it.
150 java::lang::StringBuffer *sb
151 = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
152 // Skip inner classes
154 jint ci = name->indexOf('$');
158 cn = name->substring (0, ci);
160 = (sb->append (cn)->toString ())->replace ('.', '-');
162 using namespace ::java::lang;
163 Runtime *rt = Runtime::getRuntime();
165 _Jv_Utf8Const *name_u = NULL;
167 // Compare against `3' because that is the length of "lib".
168 while (! klass && so_base_name && so_base_name->length() > 3)
170 if (lib_control == LIB_CACHE)
172 // If we've already tried this name, we're done.
173 if (tried_libraries->contains(so_base_name))
175 tried_libraries->add(so_base_name);
178 jboolean loaded = rt->loadLibraryInternal (so_base_name);
180 jint nd = so_base_name->lastIndexOf ('-');
184 so_base_name = so_base_name->substring (0, nd);
189 name_u = _Jv_makeUtf8Const (name);
190 klass = _Jv_FindClassInCache (name_u);
196 definePackageForNative(name);
202 java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
204 // We try the boot loader first, so that the endorsed directory
205 // overrides compiled-in classes.
208 klass = bootLoader->bootLoadClass(name);
211 _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
212 klass = _Jv_FindClassInCache (utf);
215 klass = nativeFindClass(name);
218 // We never want to return a class without its supers linked.
219 // It isn't clear from the spec, but this is what other
220 // implementations do in practice.
222 resolveClass (klass);
224 _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
226 definePackageForNative(name);