📄 java_tool.cpp
字号:
}
str = env->GetStringUTFChars(value, NULL);
if (strcmp(str, "utf-16le") == 0)
isUTF16 = JNI_TRUE;
else
isUTF16 = JNI_FALSE;
env->ReleaseStringUTFChars(value, str);
}
/*
* Returns a new Java string object for the specified platform string.
*/
static jstring NewPlatformString(JNIEnv *env, char *s)
{
int len = strlen(s);
jclass cls;
jmethodID mid;
jbyteArray ary;
if (isUTF16)
return env->NewStringUTF(s);
NULL_CHECK0(cls = env->FindClass("java/lang/String"));
NULL_CHECK0(mid = env->GetMethodID(cls, "<init>", "([B)V"));
ary = env->NewByteArray(len);
if (ary != 0) {
jstring str = 0;
env->SetByteArrayRegion(ary, 0, len, (jbyte *)s);
if (!env->ExceptionOccurred()) {
str = (jstring)env->NewObject(cls, mid, ary);
}
env->DeleteLocalRef(ary);
return str;
}
return 0;
}
/*
* Returns a new array of Java string objects for the specified
* array of platform strings.
*/
static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
{
jarray cls;
jarray ary;
int i;
NULL_CHECK0(cls = (jarray)env->FindClass("java/lang/String"));
NULL_CHECK0(ary = (jarray)env->NewObjectArray(strc,(_jclass*) cls, 0));
for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++);
NULL_CHECK0(str);
env->SetObjectArrayElement((_jobjectArray*)ary, i, str);
env->DeleteLocalRef(str);
}
return (_jobjectArray*)ary;
}
/*
* Loads a class, convert the '.' to '/'.
*/
static jclass LoadClass(JNIEnv *env, char *name)
{
char *buf = (char*)MemAlloc(strlen(name) + 1);
char *s = buf, *t = name, c;
jclass cls;
jlong start, end;
if (debug)
start = CounterGet();
do {
c = *t++;
*s++ = (c == '.') ? '/' : c;
} while (c != '\0');
cls = env->FindClass(buf);
free(buf);
if (debug) {
end = CounterGet();
printf("%ld micro seconds to load main class\n",
(long)(jint)Counter2Micros(end-start));
printf("----_JAVA_LAUNCHER_DEBUG----\n");
}
return cls;
}
/*
* Returns the main class name for the specified jar file.
*/
static jstring GetMainClassName(JNIEnv *env, char *jarname)
{
#define MAIN_CLASS "Main-Class"
jclass cls;
jmethodID mid;
jobject jar, man, attr;
jstring str, result = 0;
NULL_CHECK0(cls = env->FindClass("java/util/jar/JarFile"));
NULL_CHECK0(mid = env->GetMethodID(cls, "<init>",
"(Ljava/lang/String;)V"));
NULL_CHECK0(str = NewPlatformString(env, jarname));
NULL_CHECK0(jar = env->NewObject(cls, mid, str));
NULL_CHECK0(mid = env->GetMethodID(cls, "getManifest",
"()Ljava/util/jar/Manifest;"));
man = env->CallObjectMethod(jar, mid);
if (man != 0) {
NULL_CHECK0(mid = env->GetMethodID(
env->GetObjectClass(man),
"getMainAttributes",
"()Ljava/util/jar/Attributes;"));
attr = env->CallObjectMethod(man, mid);
if (attr != 0) {
NULL_CHECK0(mid = env->GetMethodID(
env->GetObjectClass(attr),
"getValue",
"(Ljava/lang/String;)Ljava/lang/String;"));
NULL_CHECK0(str = (_jstring*)NewPlatformString(env, MAIN_CLASS));
result = (_jstring*)env->CallObjectMethod(attr, mid, str);
}
}
return result;
}
#ifdef JAVA_ARGS
static char *java_args[] = JAVA_ARGS;
static char *app_classpath[] = APP_CLASSPATH;
#define NUM_ARGS (sizeof(java_args) / sizeof(char *))
#define NUM_APP_CLASSPATH (sizeof(app_classpath) / sizeof(char *))
/*
* For tools convert 'javac -J-ms32m' to 'java -ms32m ...'
*/
static void TranslateDashJArgs(int *pargc, char ***pargv)
{
int argc = *pargc;
char **argv = *pargv;
int nargc = argc + NUM_ARGS;
char **nargv = MemAlloc((nargc + 1) * sizeof(char *));
int i;
*pargc = nargc;
*pargv = nargv;
/* Copy the VM arguments (i.e. prefixed with -J) */
for (i = 0; i < NUM_ARGS; i++) {
char *arg = java_args[i];
if (arg[0] == '-' && arg[1] == 'J') {
*nargv++ = arg + 2;
}
}
for (i = 0; i < argc; i++) {
char *arg = argv[i];
if (arg[0] == '-' && arg[1] == 'J') {
if (arg[2] == '\0') {
fprintf(stderr, "Error: the -J option should not be followed by a space.\n");
exit(1);
}
*nargv++ = arg + 2;
}
}
/* Copy the rest of the arguments */
for (i = 0; i < NUM_ARGS; i++) {
char *arg = java_args[i];
if (arg[0] != '-' || arg[1] != 'J') {
*nargv++ = arg;
}
}
for (i = 0; i < argc; i++) {
char *arg = argv[i];
if (arg[0] != '-' || arg[1] != 'J') {
*nargv++ = arg;
}
}
*nargv = 0;
}
/*
* For our tools, we try to add 3 VM options:
* -Denv.class.path=<envcp>
* -Dapplication.home=<apphome>
* -Djava.class.path=<appcp>
* <envcp> is the user's setting of CLASSPATH -- for instance the user
* tells javac where to find binary classes through this environment
* variable. Notice that users will be able to compile against our
* tools classes (sun.tools.javac.Main) only if they explicitly add
* tools.jar to CLASSPATH.
* <apphome> is the directory where the application is installed.
* <appcp> is the classpath to where our apps' classfiles are.
*/
static jboolean AddApplicationOptions()
{
char *s, *envcp, *appcp, *apphome;
char home[MAXPATHLEN]; /* application home */
char separator[] = { PATH_SEPARATOR, '\0' };
int size, i;
int strlenHome;
s = getenv("CLASSPATH");
if (s) {
/* 40 for -Denv.class.path= */
envcp = (char *)MemAlloc(strlen(s) + 40);
sprintf(envcp, "-Denv.class.path=%s", s);
AddOption(envcp, NULL);
}
if (!GetApplicationHome(home, sizeof(home))) {
fprintf(stderr, "Can't determine application home\n");
return JNI_FALSE;
}
/* 40 for '-Dapplication.home=' */
apphome = (char *)MemAlloc(strlen(home) + 40);
sprintf(apphome, "-Dapplication.home=%s", home);
AddOption(apphome, NULL);
/* How big is the application's classpath? */
size = 40; /* 40: "-Djava.class.path=" */
strlenHome = strlen(home);
for (i = 0; i < NUM_APP_CLASSPATH; i++) {
size += strlenHome + strlen(app_classpath[i]) + 1; /* 1: separator */
}
appcp = (char *)MemAlloc(size + 1);
strcpy(appcp, "-Djava.class.path=");
for (i = 0; i < NUM_APP_CLASSPATH; i++) {
strcat(appcp, home); /* c:\program files\myapp */
strcat(appcp, app_classpath[i]); /* \lib\myapp.jar */
strcat(appcp, separator); /* ; */
}
appcp[strlen(appcp)-1] = '\0'; /* remove trailing path separator */
AddOption(appcp, NULL);
return JNI_TRUE;
}
#endif
/*
* Prints the version information from the java.version and other properties.
*/
static void PrintJavaVersion(JNIEnv *env)
{
jclass ver;
jmethodID print;
NULL_CHECK(ver = (jclass)env->FindClass("sun/misc/Version"));
NULL_CHECK(print = (jmethodID)env->GetStaticMethodID(ver, "print", "()V"));
env->CallStaticVoidMethod(ver, print);
}
/*
* Prints default usage message.
*/
static void PrintUsage(void)
{
int i;
fprintf(stdout,
"Usage: %s [-options] class [args...]\n"
" (to execute a class)\n"
" or %s -jar [-options] jarfile [args...]\n"
" (to execute a jar file)\n"
"\n"
"where options include:\n",
progname,
progname);
#ifdef sparc
fprintf(stdout,
" -d32\n"
" use a 32-bit data model if available\n"
" -d64\n"
" use a 64-bit data model if available\n");
#endif
for (i=0; i<knownVMsCount; i++) {
if (knownVMs[i].flag == VM_KNOWN)
fprintf(stdout, " %s\t to select the \"%s\" VM\n",
knownVMs[i].name, knownVMs[i].name+1);
}
for (i=0; i<knownVMsCount; i++) {
if (knownVMs[i].flag == VM_ALIASED_TO)
fprintf(stdout, " %s\t is a synonym for "
"the \"%s\" VM [deprecated]\n",
knownVMs[i].name, knownVMs[i].alias+1);
}
fprintf(stdout,
" The default VM is %s.\n\n", knownVMs[0].name+1);
fprintf(stdout,
" -cp -classpath <directories and zip/jar files separated by %c>\n"
" set search path for application classes and resources\n"
" -D<name>=<value>\n"
" set a system property\n"
" -verbose[:class|gc|jni]\n"
" enable verbose output\n"
" -version print product version and exit\n"
" -showversion print product version and continue\n"
" -? -help print this help message\n"
" -X print help on non-standard options\n"
" -ea[:<packagename>...|:<classname>]\n"
" -enableassertions[:<packagename>...|:<classname>]\n"
" enable assertions\n"
" -da[:<packagename>...|:<classname>]\n"
" -disableassertions[:<packagename>...|:<classname>]\n"
" disable assertions\n"
" -esa | -enablesystemassertions\n"
" enable system assertions\n"
" -dsa | -disablesystemassertions\n"
" disable system assertions\n"
,PATH_SEPARATOR);
}
/*
* Print usage message for -X options.
*/
static jint PrintXUsage(void)
{
char path[MAXPATHLEN];
char buf[128];
int n;
FILE *fp;
GetXUsagePath(path, sizeof(path));
fp = fopen(path, "r");
if (fp == 0) {
fprintf(stderr, "Can't open %s\n", path);
return 1;
}
while ((n = fread(buf, 1, sizeof(buf), fp)) != 0) {
fwrite(buf, 1, n, stdout);
}
fclose(fp);
return 0;
}
/*
* Read the jvm.cfg file and fill the knownJVMs[] array.
*/
static jint ReadKnownVMs(const char *jrepath)
{
char *arch = (char *)GetArch(); /* like sparcv9 */
FILE *jvmCfg;
char jvmCfgName[MAXPATHLEN+20];
char line[MAXPATHLEN+20];
int cnt = 0;
int lineno = 0;
jlong start, end;
int vmType;
char *tmpPtr;
char *altVMName;
static char *whiteSpace = " \t";
if(debug)
{
start = CounterGet();
}
strcpy(jvmCfgName, jrepath);
strcat(jvmCfgName, PATHSEP "lib" PATHSEP);
strcat(jvmCfgName, arch);
strcat(jvmCfgName, PATHSEP "jvm.cfg");
jvmCfg = fopen(jvmCfgName, "r");
if (jvmCfg == NULL)
{
fprintf(stderr, "Error: could not open `%s'\n", jvmCfgName);
exit(1);
}
while(fgets(line, sizeof(line), jvmCfg) != NULL)
{
vmType = VM_UNKNOWN;
lineno++;
if (line[0] == '#')
continue;
if(line[0] != '-')
{
fprintf(stderr, "Warning: no leading - on line %d of `%s'\n",
lineno, jvmCfgName);
}
if(cnt >= knownVMsLimit)
{
GrowKnownVMs(cnt);
}
line[strlen(line)-1] = '\0'; /* remove trailing newline */
tmpPtr = line + strcspn(line, whiteSpace);
if (*tmpPtr == 0)
{
fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
lineno, jvmCfgName);
}
else
{
/* Null-terminate this string for strdup below */
*tmpPtr++ = 0;
tmpPtr += strspn(tmpPtr, whiteSpace);
if (*tmpPtr == 0)
{
fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
lineno, jvmCfgName);
}
else
{
if (!strncmp(tmpPtr, "KNOWN", strlen("KNOWN")))
{
vmType = VM_KNOWN;
}
else
if (!strncmp(tmpPtr, "ALIASED_TO", strlen("ALIASED_TO")))
{
tmpPtr += strcspn(tmpPtr, whiteSpace);
if (*tmpPtr != 0)
{
tmpPtr += strspn(tmpPtr, whiteSpace);
}
if (*tmpPtr == 0)
{
fprintf(stderr, "Warning: missing VM alias on line %d of `%s'\n",
lineno, jvmCfgName);
}
else
{
/* Null terminate altVMName */
altVMName = tmpPtr;
tmpPtr += strcspn(tmpPtr, whiteSpace);
*tmpPtr = 0;
vmType = VM_ALIASED_TO;
}
}
else
if(!strncmp(tmpPtr, "WARN", strlen("WARN")))
{
vmType = VM_WARN;
}
else
if(!strncmp(tmpPtr, "ERROR", strlen("ERROR")))
{
vmType = VM_ERROR;
}
else
{
fprintf(stderr, "Warning: unknown VM type %s on line %d of `%s'\n",
vmType, lineno, jvmCfgName);
vmType = VM_KNOWN;
}
}
}
if (debug)
printf("jvm.cfg[%d] = ->%s<-\n", cnt, line);
if(vmType != VM_UNKNOWN)
{
knownVMs[cnt].name = strdup(line);
knownVMs[cnt].flag = vmType;
if (vmType == VM_ALIASED_TO)
{
knownVMs[cnt].alias = strdup(altVMName);
}
cnt++;
}
}
fclose(jvmCfg);
knownVMsCount = cnt;
if(debug)
{
end = CounterGet();
printf("%ld micro seconds to parse jvm.cfg\n",(jint)Counter2Micros(end-start));
}
return cnt;
}
static void GrowKnownVMs(int minimum)
{
struct vmdesc* newKnownVMs;
int newMax;
newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS : (2 * knownVMsLimit));
if (newMax <= minimum) {
newMax = minimum;
}
newKnownVMs = (struct vmdesc*) malloc(newMax * sizeof(struct vmdesc));
if (knownVMs != NULL) {
memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc));
}
free(knownVMs);
knownVMs = newKnownVMs;
knownVMsLimit = newMax;
}
/* Returns index of VM or -1 if not found */
static int KnownVMIndex(const char* name)
{
int i;
if (strncmp(name, "-J", 2) == 0) name += 2;
for (i = 0; i < knownVMsCount; i++) {
if (!strcmp(name, knownVMs[i].name)) {
return i;
}
}
return -1;
}
//AttachCurrentThread()
static void FreeKnownVMs()
{
int i;
for (i = 0; i < knownVMsCount; i++) {
free(knownVMs[i].name);
knownVMs[i].name = NULL;
}
free(knownVMs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -