findinjar.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 790 行 · 第 1/2 页
C
790 行
/* * findInJar.c * Search the CLASSPATH for the given class or property name. * * Copyright (c) 1996, 1997, 1998, 1999 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "debug.h"#include "config-std.h"#include "config-io.h"#include "config-mem.h"#include "gtypes.h"#include "support.h"#include "file.h"#include "exception.h"#include "readClass.h"#include "system.h"#include "errors.h"#include "lerrno.h"#include "locks.h"#include "files.h"#include "baseClasses.h"#include "classMethod.h"#include "external.h"#include "jar.h"#include "jsyscall.h"#include "jni.h"#include "classpath.h"#include "stringSupport.h"#include "stats.h"#include "access.h"#include "gcj/gcj.h"#include "defs.h"#if defined(HAVE_SYS_TYPES_H)#include <sys/types.h>#endif /* defined(HAVE_SYS_TYPES_H) */#include <zzip/zzip.h>#ifdef __riscos__#include <unixlib/local.h>#endif/* Handle Manifest Class-Path attribute. It will be better to handle that in a ClassLoader. */#define HANDLE_MANIFEST_CLASSPATH 1#define KLASSES_JAR "rt.jar"classpathEntry* classpath;const char* realClassPath;char* realBootClassPath;void initClasspath(void);static int getClasspathType(const char*);static void discoverClasspath(const char*);static void makeClasspath(char*);static void findClassInJar(char*, classFile*, struct _errorInfo*);static int insertClasspath(const char* cp, int prepend);#if defined(HANDLE_MANIFEST_CLASSPATH)static int isEntryInClasspath(const char*);static char* getManifestMainAttribute(ZZIP_DIR*, const char*);static void handleManifestClassPath (classpathEntry *);#endif/* * Find the named class in a directory or JAR file. * Returns class if successful, NULL otherwise. */Hjava_lang_Class*findClass(classEntry* centry, errorInfo *einfo){ char *buf; classFile hand; const char* cname; Hjava_lang_Class* class = NULL; cname = centry->name->data;#if defined(HAVE_GCJ_SUPPORT) /* * XXX: for now, prefer *any* classes given in a .so file * What we really want is to have separate lists for each .so module * so that we can search for classes in the order that the classpath * specifies. * A good reimplementation would use a global hashtable to map * all available names to the sources from which they'd be loaded. */ class = gcjFindClassByUtf8Name(cname, einfo); if (class != 0) { if (Kaffe_JavaVMArgs.enableVerboseClassloading) { /* XXX could say from where, but see above */ dprintf("Loading precompiled %s\n", cname); }DBG(GCJ, dprintf(__FUNCTION__": adding class %s to pool@%p\n", cname, centry); ); class->centry = centry; assert(CLASS_GCJ(class)); return (class); }#endif /* Look for the class */DBG(CLASSLOOKUP, dprintf("Scanning for class %s\n", cname); ); buf = checkPtr(KMALLOC(strlen(cname) + 8)); sprintf(buf, "%s.class", cname); /* Find class in Jar file */ findClassInJar(buf, &hand, einfo); KFREE(buf); if (hand.type == CP_NULLCLASS) { discardErrorInfo(einfo); postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "Class %s has a null length", centry->name->data); return (NULL); } if (hand.type == CP_INVALID) { /* We should only throw a ClassNotFoundException. */ discardErrorInfo(einfo); postExceptionMessage(einfo, JAVA_LANG(ClassNotFoundException), "%s", centry->name->data); return (NULL); } switch (hand.type) { case CP_DIR: case CP_ZIPFILE: class = newClass(); if (class == NULL) { postOutOfMemory(einfo); KFREE(hand.mem); return (NULL); } utf8ConstAssign(class->name, centry->name); class->centry = centry; class = readClass(class, &hand, NULL, einfo); if (hand.base != NULL) {#if defined(KAFFE_STATS) if (hand.type == CP_ZIPFILE) { addToCounter(&jarmem, "vmmem-jar files", 1, -(jlong)GCSIZEOF(hand.base)); }#endif KFREE(hand.mem); } return (class); case CP_INVALID: case CP_SOFILE: case CP_BYTEARRAY: default: break; } /* * Certain classes are essential. If we don't find them then * abort. Note that loadStaticClass will abort for essential * classes, so we only have to check for these two here. */ if (strcmp(cname, "java/lang/ClassNotFoundException") == 0 || strcmp(cname, "java/lang/Object") == 0) { dprintf("Cannot find essential class '%s' in class library ... aborting.\n", cname); KAFFEVM_ABORT(); } return (NULL);}static iStaticLock jarlock;/* * Locate the given name in the CLASSPATH. Fill in the provided * classFile handle with a buffer containing the class (or * set the hand->type to CP_INVALID). * * May write into cname. */static voidfindClassInJar(char* cname, classFile* hand, errorInfo *einfo){ char *buf; int fp; classpathEntry* ptr; int i; int rc; /* Look for the class */DBG(CLASSLOOKUP, dprintf("Scanning for element %s\n", cname); ); hand->type = CP_INVALID; /* One into the jar at once */ lockStaticMutex(&jarlock); for (ptr = classpath; ptr != 0; ptr = ptr->next) {DBG(CLASSLOOKUP,dprintf("Processing classpath entry '%s'\n", ptr->path); ); switch (ptr->type) { case CP_ZIPFILE: { ZZIP_FILE * entry; unsigned char* data; zzip_size_t length;DBG(CLASSLOOKUP, dprintf("Opening JAR file %s for %s\n", ptr->path, cname); ); if (ptr->u.jar == 0) { ptr->u.jar = zzip_opendir(ptr->path); if (ptr->u.jar == 0) { break; }#if defined(HANDLE_MANIFEST_CLASSPATH) /* handle Manifest Class-Path attribute */ handleManifestClassPath (ptr);#endif } entry = zzip_file_open(ptr->u.jar, cname, 0); if (entry == 0) { break; } length = getUncompressedSize(entry); if (0 == length) { hand->type = CP_NULLCLASS; goto done; } data = getDataJarFile(entry); zzip_file_close(entry); if (data == 0) { postExceptionMessage(einfo, JAVA_IO(IOException), "Couldn't extract data from jar %s", ptr->path); goto done; } classFileInit(hand, data, data, length, CP_ZIPFILE); if (Kaffe_JavaVMArgs.enableVerboseClassloading) { dprintf("Loading %s(%s)\n", cname, ptr->path); } goto done; } case CP_DIR: { struct stat sbuf; unsigned char* data; buf = checkPtr(KMALLOC(strlen(ptr->path) + strlen(file_separator) + strlen(cname) + 1)); sprintf(buf, "%s%s%s", ptr->path, file_separator, cname);DBG(CLASSLOOKUP, dprintf("Opening java file %s for %s\n", buf, cname); ); rc = KOPEN(buf, O_RDONLY|O_BINARY, 0, &fp); KFREE(buf); /* if we can't open the file, we keep looking */ if (rc) { break; /* will be NoClassDefFoundError */ } /* if we can open the file, but cannot stat or read it, * we flag an IOException (!?) */ if ((rc = KFSTAT(fp, &sbuf)) != 0) { KCLOSE(fp); postExceptionMessage(einfo, JAVA_IO(IOException), "Couldn't fstat: %s", SYS_ERROR(rc)); goto done; } /* * XXX Whlist bogus, a zero-length class file poses * no problems for this code. Assume the user of * the file will find that problem... */ data = NULL; if (sbuf.st_size > 0) { data = KMALLOC((size_t)sbuf.st_size); if (data == 0) { postOutOfMemory(einfo); goto done; } } i = 0; while (i < sbuf.st_size) { ssize_t j; rc = KREAD(fp, data, (size_t)(sbuf.st_size - i), &j); if (rc != 0) { postExceptionMessage(einfo, JAVA_IO(IOException), "Couldn't read: %s", SYS_ERROR(rc)); KFREE(data); break; } else { if (j > 0) { /* more data */ i += j; } else { /* end of file */ break; } } } classFileInit(hand, data, data, (unsigned)sbuf.st_size, CP_DIR); KCLOSE(fp); if (Kaffe_JavaVMArgs.enableVerboseClassloading) { dprintf("Loading %s\n", cname); } goto done; } /* Ignore bad entries */ default: /* XXX warning.... */ break; } } /* If we call out the loop then we didn't find anything */ assert (hand->type == CP_INVALID); /* cut off the ".class" suffix for the exception msg */ cname[strlen(cname) - strlen(".class")] = '\0'; /* * Technically, we're just loading a file, so use * FileNotFoundException. */ postExceptionMessage(einfo, JAVA_IO(FileNotFoundException), "%s", cname); done:; unlockStaticMutex(&jarlock);}/* * Initialise class path. */voidinitClasspath(void){ const char* cp; const char* hm; size_t len; classpathEntry* ptr; DBG(INIT, dprintf("initClasspath()\n"); ); cp = Kaffe_JavaVMArgs.bootClasspath; hm = Kaffe_JavaVMArgs.classhome; initStaticLock(&jarlock); if (cp != NULL && cp[0] != '\0') { /* cp may reside in read-only memory, but * makeClasspath writes to it */ char *writable_cp = KMALLOC(strlen(cp) + 1); strcpy(writable_cp, cp); makeClasspath(writable_cp); KFREE(writable_cp); } else { if (hm) { discoverClasspath(hm); } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?