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
,
51 _Jv_RegisterInitiatingLoader (klass
, klass
->loader
);
56 klass
= new java::lang::Class ();
58 // Synchronize on the class, so that it is not attempted initialized
59 // until we're done loading.
60 JvSynchronize
sync (klass
);
62 // Record the defining loader. For the bootstrap class loader,
64 if (loader
!= bootLoader
)
65 klass
->loader
= loader
;
69 _Jv_Utf8Const
*name2
= _Jv_makeUtf8Const (name
);
71 if (! _Jv_VerifyClassName (name2
))
72 throw new java::lang::ClassFormatError
73 (JvNewStringLatin1 ("erroneous class name"));
78 _Jv_Utf8Const
*found_name
= NULL
;
81 _Jv_DefineClass (klass
, data
, offset
, length
, pd
, &found_name
);
83 catch (java::lang::Throwable
*ex
)
85 klass
->state
= JV_STATE_ERROR
;
88 if (found_name
!= NULL
)
89 _Jv_UnregisterInitiatingLoader (klass
, klass
->loader
);
91 // If EX is not a ClassNotFoundException, that's ok, because we
92 // account for the possibility in defineClass().
96 // if everything proceeded sucessfully, we're loaded.
97 JvAssert (klass
->state
== JV_STATE_LOADED
);
103 StringBuffer
*sb
= new StringBuffer();
106 sb
->append(JvNewStringLatin1("found class file for class "));
110 sb
->append(JvNewStringLatin1("found unnamed class file"));
111 sb
->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
112 throw new VirtualMachineError(sb
->toString());
118 java::lang::ClassLoader
*
119 java::lang::VMClassLoader::getSystemClassLoaderInternal()
121 _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$
);
122 _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance
);
123 return gnu::gcj::runtime::ExtensionClassLoader::system_instance
;
127 java::lang::VMClassLoader::getPrimitiveClass (jchar type
)
130 sig
[0] = (char) type
;
132 // Note: this cannot return NULL, since the input is always correct.
133 return _Jv_FindClassFromSignature (sig
, NULL
);
137 java::lang::VMClassLoader::initBootLoader(jstring libdir
)
139 bootLoader
= new gnu::gcj::runtime::BootClassLoader(libdir
);
143 java::lang::VMClassLoader::nativeFindClass (jstring name
)
147 if (lib_control
!= LIB_NEVER
)
149 // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
150 // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
151 // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
152 // these causes the class to appear in the cache, then use it.
153 java::lang::StringBuffer
*sb
154 = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
155 // Skip inner classes
157 jint ci
= name
->indexOf('$');
161 cn
= name
->substring (0, ci
);
163 = (sb
->append (cn
)->toString ())->replace ('.', '-');
165 using namespace ::java::lang
;
166 Runtime
*rt
= Runtime::getRuntime();
168 _Jv_Utf8Const
*name_u
= NULL
;
170 // Compare against `3' because that is the length of "lib".
171 while (! klass
&& so_base_name
&& so_base_name
->length() > 3)
173 if (lib_control
== LIB_CACHE
)
175 // If we've already tried this name, we're done.
176 if (tried_libraries
->contains(so_base_name
))
178 tried_libraries
->add(so_base_name
);
181 jboolean loaded
= rt
->loadLibraryInternal (so_base_name
);
183 jint nd
= so_base_name
->lastIndexOf ('-');
187 so_base_name
= so_base_name
->substring (0, nd
);
192 name_u
= _Jv_makeUtf8Const (name
);
193 klass
= _Jv_FindClassInCache (name_u
);
199 definePackageForNative(name
);
205 java::lang::VMClassLoader::loadClass(jstring name
, jboolean resolve
)
207 // We try the boot loader first, so that the endorsed directory
208 // overrides compiled-in classes.
211 klass
= bootLoader
->bootLoadClass(name
);
214 _Jv_Utf8Const
*utf
= _Jv_makeUtf8Const (name
);
215 klass
= _Jv_FindClassInCache (utf
);
218 klass
= nativeFindClass(name
);
221 // We never want to return a class without its supers linked.
222 // It isn't clear from the spec, but this is what other
223 // implementations do in practice.
225 resolveClass (klass
);
227 _Jv_Linker::wait_for_state (klass
, JV_STATE_LOADING
);
229 definePackageForNative(name
);