1 // natVMClassLoader.cc - VMClassLoader native methods
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 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>
39 java::lang::VMClassLoader::defineClass (java::lang::ClassLoader
*loader
,
44 java::security::ProtectionDomain
*pd
)
46 jclass klass
= VMCompiler::compileClass(loader
, name
, data
,
52 klass
= new java::lang::Class ();
54 // Synchronize on the class, so that it is not attempted initialized
55 // until we're done loading.
56 JvSynchronize
sync (klass
);
58 // Record the defining loader. For the bootstrap class loader,
60 if (loader
!= bootLoader
)
61 klass
->loader
= loader
;
65 _Jv_Utf8Const
*name2
= _Jv_makeUtf8Const (name
);
67 if (! _Jv_VerifyClassName (name2
))
68 throw new java::lang::ClassFormatError
69 (JvNewStringLatin1 ("erroneous class name"));
74 _Jv_Utf8Const
*found_name
= NULL
;
77 _Jv_DefineClass (klass
, data
, offset
, length
, pd
, &found_name
);
79 catch (java::lang::Throwable
*ex
)
81 klass
->state
= JV_STATE_ERROR
;
84 if (found_name
!= NULL
)
85 _Jv_UnregisterInitiatingLoader (klass
, klass
->loader
);
87 // If EX is not a ClassNotFoundException, that's ok, because we
88 // account for the possibility in defineClass().
92 // if everything proceeded sucessfully, we're loaded.
93 JvAssert (klass
->state
== JV_STATE_LOADED
);
100 java::lang::ClassLoader
*
101 java::lang::VMClassLoader::getSystemClassLoaderInternal()
103 _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$
);
104 _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance
);
105 return gnu::gcj::runtime::ExtensionClassLoader::system_instance
;
109 java::lang::VMClassLoader::getPrimitiveClass (jchar type
)
112 sig
[0] = (char) type
;
114 // Note: this cannot return NULL, since the input is always correct.
115 return _Jv_FindClassFromSignature (sig
, NULL
);
119 java::lang::VMClassLoader::initBootLoader(jstring libdir
)
121 bootLoader
= new gnu::gcj::runtime::BootClassLoader(libdir
);
125 java::lang::VMClassLoader::nativeFindClass (jstring name
)
129 if (lib_control
!= LIB_NEVER
)
131 // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
132 // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
133 // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
134 // these causes the class to appear in the cache, then use it.
135 java::lang::StringBuffer
*sb
136 = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
137 // Skip inner classes
139 jint ci
= name
->indexOf('$');
143 cn
= name
->substring (0, ci
);
145 = (sb
->append (cn
)->toString ())->replace ('.', '-');
147 using namespace ::java::lang
;
148 Runtime
*rt
= Runtime::getRuntime();
150 _Jv_Utf8Const
*name_u
= NULL
;
152 // Compare against `3' because that is the length of "lib".
153 while (! klass
&& so_base_name
&& so_base_name
->length() > 3)
155 if (lib_control
== LIB_CACHE
)
157 // If we've already tried this name, we're done.
158 if (tried_libraries
->contains(so_base_name
))
160 tried_libraries
->add(so_base_name
);
163 jboolean loaded
= rt
->loadLibraryInternal (so_base_name
);
165 jint nd
= so_base_name
->lastIndexOf ('-');
169 so_base_name
= so_base_name
->substring (0, nd
);
174 name_u
= _Jv_makeUtf8Const (name
);
175 klass
= _Jv_FindClassInCache (name_u
);
181 definePackageForNative(name
);
187 java::lang::VMClassLoader::loadClass(jstring name
, jboolean resolve
)
189 // We try the boot loader first, so that the endorsed directory
190 // overrides compiled-in classes.
193 klass
= bootLoader
->bootLoadClass(name
);
196 _Jv_Utf8Const
*utf
= _Jv_makeUtf8Const (name
);
197 klass
= _Jv_FindClassInCache (utf
);
200 klass
= nativeFindClass(name
);
203 // We never want to return a class without its supers linked.
204 // It isn't clear from the spec, but this is what other
205 // implementations do in practice.
207 resolveClass (klass
);
209 _Jv_Linker::wait_for_state (klass
, JV_STATE_LOADING
);
211 definePackageForNative(name
);