Skip to content

Instantly share code, notes, and snippets.

@aantron
Created January 9, 2017 18:09
Show Gist options
  • Save aantron/b2ed179676ae8e697b03ed524f56891f to your computer and use it in GitHub Desktop.
Save aantron/b2ed179676ae8e697b03ed524f56891f to your computer and use it in GitHub Desktop.
Java classes inlined into object file, plus loader
// This function calls the JNI routine DefineClass for each class in the
// in-memory class table (see java-classes.h). The class loader parameter passed
// to define class is the result of calling ClassLoader.getSystemClassLoader().
jthrowable java_load_classes()
{
JNIEnv *environment;
jclass class_loader;
jmethodID get_system_loader;
jobject system_loader;
jthrowable exception;
jint jni_result;
// Get the JNI environment structure for the current thread.
jni_result = virtual_machine->GetEnv((void**)&environment, JNI_REQUIRED);
if(jni_result != JNI_OK)
return false;
// Find the standard ClassLoader class.
class_loader = environment->FindClass("java/lang/ClassLoader");
if(class_loader == NULL)
{
java_record_exception(environment, exception);
return exception;
}
// Get the system class loader. The classes loaded from memory will be
// marked as having been loaded using this class loader.
get_system_loader =
environment->GetStaticMethodID(class_loader, "getSystemClassLoader",
"()Ljava/lang/ClassLoader;");
if(get_system_loader == NULL)
{
java_record_exception(environment, exception);
return exception;
}
system_loader =
environment->CallStaticObjectMethod(class_loader, get_system_loader);
// Iterate through the in-memory class table. For each entry, load the
// corresponding class.
for(int class_index = 0; class_index < class_count; ++class_index)
{
if(environment->DefineClass(classes[class_index].name, system_loader,
(const jbyte*)classes[class_index].body,
classes[class_index].body_length) == NULL)
{
java_record_exception(environment, exception);
return exception;
}
}
return NULL;
}
/** @brief Causes the virtual machine to load Java classes stored in the program
image.
To avoid the need to distribute a <code>.jar</code> file or a directory tree
with several <code>.class</code> files together with the native portion of
the FUSE driver, the Java classes necessary for the FUSE driver are stored
inline in the native program image. They are therefore available in memory
by the time the image has been loaded and the driver started.
This function commands the virtual machine to load these classes. After
this, the native code may freely call any of the Java code in the classes.
The classes that are loaded are those listed in the table found in the
generated file <code>java-classes.c</code>. The table itself is declared in
the file <code>java-classes.h</code>. <code>java-classes.c</code> is
typically generated by running the Java program
<code>build.MakeClassesImage</code> with the appropriate arguments from the
<code>Makefile</code>.
@return <code>NULL</code> if the classes are loaded successfully. If there
is an error, a Java exception object descriptive of the error is
returned instead.
*/
jthrowable java_load_classes(void);
/** @file java-classes.h
@brief Definition of the inline Java class table.
The inline Java class table contains pointers to a series of complete class
files, and the corresponding Java modified UTF-8-encoded class names. Each
class file is stored directly within the native binary image, and loaded by
the driver at startup. This removes the need to distribute the classes
separately from the native driver in a JAR file, and therefore the need to
somehow communicate the path to the JAR file to the native binary.
*/
#ifndef _JAVA_CLASSES_H_
#define _JAVA_CLASSES_H_
/// Class table entry.
struct class_info
{
/// Class name, encoded in Java modified UTF-8.
const char *name;
/// Class body. This is the quoted contents of the .class file for the
/// class.
const char *body;
/// Length, in bytes, of the class body.
const size_t body_length;
};
/// Number of classes in the class table.
extern const int class_count;
/// The class table itself.
extern const class_info classes[];
#endif // #ifndef _JAVA_CLASSES_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment