You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Nathan Beyer <nd...@apache.org> on 2009/11/18 17:50:44 UTC
Re: svn commit: r881682 - in /harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared:
inst_agt.c instrument.c
Aren't we in a code freeze?
On Wed, Nov 18, 2009 at 12:19 AM, <re...@apache.org> wrote:
> Author: regisxu
> Date: Wed Nov 18 06:19:58 2009
> New Revision: 881682
>
> URL: http://svn.apache.org/viewvc?rev=881682&view=rev
> Log:
> delete trailing whitespace, indent code, no functional changes.
>
> Modified:
> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
>
> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c?rev=881682&r1=881681&r2=881682&view=diff
> ==============================================================================
> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c (original)
> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c Wed Nov 18 06:19:58 2009
> @@ -1,13 +1,13 @@
> -/*
> +/*
> * Licensed to the Apache Software Foundation (ASF) under one or more
> * contributor license agreements. See the NOTICE file distributed with
> * this work for additional information regarding copyright ownership.
> * The ASF licenses this file to You under the Apache License, Version 2.0
> * (the "License"); you may not use this file except in compliance with
> * the License. You may obtain a copy of the License at
> - *
> + *
> * http://www.apache.org/licenses/LICENSE-2.0
> - *
> + *
> * Unless required by applicable law or agreed to in writing, software
> * distributed under the License is distributed on an "AS IS" BASIS,
> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> @@ -39,387 +39,387 @@
>
> //call back function for ClassLoad event
> void JNICALL callbackClassFileLoadHook(jvmtiEnv *jvmti_env,
> - JNIEnv* jni_env,
> - jclass class_being_redefined,
> - jobject loader,
> - const char* name,
> - jobject protection_domain,
> - jint class_data_len,
> - const unsigned char* class_data,
> - jint* new_class_data_len,
> - unsigned char** new_class_data){
> -
> - jclass inst_class = *(gdata->inst_class);
> - jbyteArray jnew_bytes = NULL;
> - jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
> - jmethodID transform_method = *(gdata->transform_method);
> - int name_len = strlen(name);
> - jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
> -
> - //construct java byteArray for old class data and class name
> - (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
> - (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
> -
> - //invoke transform method
> - jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
> -
> - //get transform result to native char array
> - if(0 != jnew_bytes){
> - *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
> - (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
> - *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
> - (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
> - }
> - return;
> + JNIEnv* jni_env,
> + jclass class_being_redefined,
> + jobject loader,
> + const char* name,
> + jobject protection_domain,
> + jint class_data_len,
> + const unsigned char* class_data,
> + jint* new_class_data_len,
> + unsigned char** new_class_data){
> +
> + jclass inst_class = *(gdata->inst_class);
> + jbyteArray jnew_bytes = NULL;
> + jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
> + jmethodID transform_method = *(gdata->transform_method);
> + int name_len = strlen(name);
> + jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
> +
> + //construct java byteArray for old class data and class name
> + (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
> + (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
> +
> + //invoke transform method
> + jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
> +
> + //get transform result to native char array
> + if(0 != jnew_bytes){
> + *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
> + (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
> + *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
> + (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
> + }
> + return;
> }
>
> //call back function for VM init event
> void JNICALL callbackVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread){
> - jmethodID constructor;
> - static jmethodID transform_method;
> - static jmethodID premain_method;
> - static jobject inst_obj;
> - static jclass inst_class;
> - jvmtiError err;
> - AgentList *elem;
> -
> - PORT_ACCESS_FROM_ENV (env);
> - inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
> - if(NULL == inst_class){
> - (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
> - return;
> - }
> - inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
> - gdata->inst_class = &inst_class;
> -
> - constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
> - if(NULL == constructor){
> - (*env)->FatalError(env,"constructor cannot be found.");
> - return;
> - }
> -
> - inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
> - if(NULL == inst_obj){
> - (*env)->FatalError(env,"object cannot be inited.");
> - return;
> - }
> -
> - inst_obj = (*env)->NewGlobalRef(env, inst_obj);
> - gdata->inst = &inst_obj;
> -
> - transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
> - if(NULL == transform_method){
> - (*env)->FatalError(env,"transform method cannot find.");
> - return;
> - }
> - gdata->transform_method = &transform_method;
> -
> - premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
> - if(NULL == premain_method){
> - (*env)->FatalError(env,"executePremain method cannot find.");
> - return;
> - }
> - gdata->premain_method = &premain_method;
> - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
> - check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
> -
> - //parse command options and run premain class here
> - if(tail == &list){
> - return;
> - }
> - for(elem = list.next; elem != NULL; elem = list.next){
> - char *agent_options = elem->option;
> - char *class_name = elem->class_name;
> - jbyteArray joptions=NULL, jclass_name;
> - if(class_name){
> - jclass_name = (*env)->NewByteArray(env, strlen(class_name));
> - (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
> - }else{
> - goto DEALLOCATE;
> - }
> - if(agent_options){
> - joptions = (*env)->NewByteArray(env, strlen(agent_options));
> - (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
> - }
> -
> - (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
> -DEALLOCATE:
> - list.next = elem->next;
> - hymem_free_memory(elem->class_name);
> - hymem_free_memory(elem->option);
> - hymem_free_memory(elem);
> - }
> - tail = &list;
> + jmethodID constructor;
> + static jmethodID transform_method;
> + static jmethodID premain_method;
> + static jobject inst_obj;
> + static jclass inst_class;
> + jvmtiError err;
> + AgentList *elem;
> +
> + PORT_ACCESS_FROM_ENV (env);
> + inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
> + if(NULL == inst_class){
> + (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
> + return;
> + }
> + inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
> + gdata->inst_class = &inst_class;
> +
> + constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
> + if(NULL == constructor){
> + (*env)->FatalError(env,"constructor cannot be found.");
> + return;
> + }
> +
> + inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
> + if(NULL == inst_obj){
> + (*env)->FatalError(env,"object cannot be inited.");
> + return;
> + }
> +
> + inst_obj = (*env)->NewGlobalRef(env, inst_obj);
> + gdata->inst = &inst_obj;
> +
> + transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
> + if(NULL == transform_method){
> + (*env)->FatalError(env,"transform method cannot find.");
> + return;
> + }
> + gdata->transform_method = &transform_method;
> +
> + premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
> + if(NULL == premain_method){
> + (*env)->FatalError(env,"executePremain method cannot find.");
> + return;
> + }
> + gdata->premain_method = &premain_method;
> + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
> + check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
> +
> + //parse command options and run premain class here
> + if(tail == &list){
> + return;
> + }
> + for(elem = list.next; elem != NULL; elem = list.next){
> + char *agent_options = elem->option;
> + char *class_name = elem->class_name;
> + jbyteArray joptions=NULL, jclass_name;
> + if(class_name){
> + jclass_name = (*env)->NewByteArray(env, strlen(class_name));
> + (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
> + }else{
> + goto DEALLOCATE;
> + }
> + if(agent_options){
> + joptions = (*env)->NewByteArray(env, strlen(agent_options));
> + (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
> + }
> +
> + (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
> + DEALLOCATE:
> + list.next = elem->next;
> + hymem_free_memory(elem->class_name);
> + hymem_free_memory(elem->option);
> + hymem_free_memory(elem);
> + }
> + tail = &list;
> }
>
> char* Read_Manifest(JavaVM *vm, JNIEnv *env,const char *jar_name){
> - I_32 retval;
> + I_32 retval;
> #ifndef HY_ZIP_API
> - HyZipFile zipFile;
> - HyZipEntry zipEntry;
> + HyZipFile zipFile;
> + HyZipEntry zipEntry;
> #else
> - VMIZipFile zipFile;
> - VMIZipEntry zipEntry;
> + VMIZipFile zipFile;
> + VMIZipEntry zipEntry;
> #endif
> - char *result;
> - int size = 0;
> - char errorMessage[1024];
> -
> - /* Reach for the VM interface */
> - VMI_ACCESS_FROM_JAVAVM(vm);
> - PORT_ACCESS_FROM_JAVAVM(vm);
> + char *result;
> + int size = 0;
> + char errorMessage[1024];
> +
> + /* Reach for the VM interface */
> + VMI_ACCESS_FROM_JAVAVM(vm);
> + PORT_ACCESS_FROM_JAVAVM(vm);
>
> #ifdef HY_ZIP_API
> - VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
> + VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
>
> #endif /* HY_ZIP_API */
> - /* open zip file */
> + /* open zip file */
> #ifndef HY_ZIP_API
> - retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
> + retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
> #else /* HY_ZIP_API */
> - retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
> + retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
> #endif /* HY_ZIP_API */
> - if(retval){
> - sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
> - (*env)->FatalError(env, errorMessage);
> - return NULL;
> - }
> + if(retval){
> + sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
> + (*env)->FatalError(env, errorMessage);
> + return NULL;
> + }
>
> - /* get manifest entry */
> + /* get manifest entry */
> #ifndef HY_ZIP_API
> - zip_initZipEntry(privatePortLibrary, &zipEntry);
> - retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
> + zip_initZipEntry(privatePortLibrary, &zipEntry);
> + retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
> #else /* HY_ZIP_API */
> - zipFuncs->zip_initZipEntry(VMI, &zipEntry);
> - retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
> + zipFuncs->zip_initZipEntry(VMI, &zipEntry);
> + retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
> #endif /* HY_ZIP_API */
> - if (retval) {
> + if (retval) {
> #ifndef HY_ZIP_API
> - zip_freeZipEntry(PORTLIB, &zipEntry);
> + zip_freeZipEntry(PORTLIB, &zipEntry);
> #else /* HY_ZIP_API */
> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> #endif /* HY_ZIP_API */
> - sprintf(errorMessage,"failed to get entry: %d\n", retval);
> - (*env)->FatalError(env, errorMessage);
> - return NULL;
> - }
> -
> - /* read bytes */
> - size = zipEntry.uncompressedSize;
> - result = (char *)hymem_allocate_memory(size*sizeof(char));
> + sprintf(errorMessage,"failed to get entry: %d\n", retval);
> + (*env)->FatalError(env, errorMessage);
> + return NULL;
> + }
> +
> + /* read bytes */
> + size = zipEntry.uncompressedSize;
> + result = (char *)hymem_allocate_memory(size*sizeof(char));
> #ifndef HY_ZIP_API
> - retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
> + retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
> #else /* HY_ZIP_API */
> - retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
> + retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
> #endif /* HY_ZIP_API */
> - if(retval){
> + if(retval){
> #ifndef HY_ZIP_API
> - zip_freeZipEntry(PORTLIB, &zipEntry);
> + zip_freeZipEntry(PORTLIB, &zipEntry);
> #else /* HY_ZIP_API */
> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> #endif /* HY_ZIP_API */
> - sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
> - (*env)->FatalError(env, errorMessage);
> - return NULL;
> - }
> + sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
> + (*env)->FatalError(env, errorMessage);
> + return NULL;
> + }
>
> - /* free resource */
> + /* free resource */
> #ifndef HY_ZIP_API
> - zip_freeZipEntry(privatePortLibrary, &zipEntry);
> - retval = zip_closeZipFile(privatePortLibrary, &zipFile);
> + zip_freeZipEntry(privatePortLibrary, &zipEntry);
> + retval = zip_closeZipFile(privatePortLibrary, &zipFile);
> #else /* HY_ZIP_API */
> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> - retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
> + retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
> #endif /* HY_ZIP_API */
> - if (retval) {
> - sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
> - (*env)->FatalError(env, errorMessage);
> - return NULL;
> - }
> - return result;
> + if (retval) {
> + sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
> + (*env)->FatalError(env, errorMessage);
> + return NULL;
> + }
> + return result;
> }
>
> char* read_attribute(JavaVM *vm, char *manifest,char *lwrmanifest, const char * target){
> - char *pos;
> - char *end;
> - char *value;
> - int length;
> + char *pos;
> + char *end;
> + char *value;
> + int length;
> PORT_ACCESS_FROM_JAVAVM(vm);
> -
> +
> if(NULL == strstr(lwrmanifest,target)){
> - return NULL;
> - }
> -
> + return NULL;
> + }
> +
> pos = manifest+ (strstr(lwrmanifest,target) - lwrmanifest);
> - pos += strlen(target)+2;//": "
> - end = strchr(pos, '\n');
> - if(NULL == end){
> - end = manifest + strlen(manifest);
> - }
> - /* in windows, has '\r\n' in the end of line, omit '\r' */
> - if (*(end - 1) == '\r'){
> - end--;
> - }
> - length = end - pos;
> -
> - value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
> - strncpy(value, pos, length);
> - *(value+length) = '\0';
> - return value;
> + pos += strlen(target)+2;//": "
> + end = strchr(pos, '\n');
> + if(NULL == end){
> + end = manifest + strlen(manifest);
> + }
> + /* in windows, has '\r\n' in the end of line, omit '\r' */
> + if (*(end - 1) == '\r'){
> + end--;
> + }
> + length = end - pos;
> +
> + value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
> + strncpy(value, pos, length);
> + *(value+length) = '\0';
> + return value;
> }
>
> char* strlower(char * str){
> - char *temp = str;
> - while((*temp = tolower(*temp)))
> - temp++;
> - return str;
> + char *temp = str;
> + while((*temp = tolower(*temp)))
> + temp++;
> + return str;
> }
>
> -int str2bol(char *str){
> - return 0 == strcmp("true", strlower(str));
> +int str2bol(char *str){
> + return 0 == strcmp("true", strlower(str));
> }
>
> jint Parse_Options(JavaVM *vm, JNIEnv *env, jvmtiEnv *jvmti, const char *agent){
> - PORT_ACCESS_FROM_JAVAVM(vm);
> - VMI_ACCESS_FROM_JAVAVM(vm);
> -
> - AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
> - char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
> - char *jar_name, *manifest;
> - char *options = NULL;
> - char *class_name, *bootclasspath, *str_support_redefine;
> - char *bootclasspath_item;
> - char *classpath;
> - char *classpath_cpy;
> - int support_redefine = 0;
> - char *pos;
> - char *lwrmanifest;
> -
> - strcpy(agent_cpy, agent);
> - //parse jar name and options
> - pos = strchr(agent_cpy, '=');
> - if(pos>0){
> - *pos++ = 0;
> - options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
> - strcpy(options, pos);
> - }
> - jar_name =agent_cpy;
> -
> - //read jar files, find manifest entry and read bytes
> - //read attributes(premain class, support redefine, bootclasspath)
> - manifest = Read_Manifest(vm,env, jar_name);
> - lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
> - strcpy(lwrmanifest,manifest);
> - strlower(lwrmanifest);
> -
> - //jar itself added to bootclasspath
> - check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
> - classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
> - strcpy(classpath_cpy,classpath);
> - strcat(classpath_cpy,";");
> - strcat(classpath_cpy,jar_name);
> - check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
> - hymem_free_memory(classpath_cpy);
> - hymem_free_memory(jar_name);
> -
> - //save options, save class name, add to agent list
> - class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
> - if(NULL == class_name){
> - hymem_free_memory(lwrmanifest);
> - hymem_free_memory(manifest);
> - (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
> - }
> - new_elem->option = options;
> - new_elem->class_name = class_name;
> - new_elem->next = NULL;
> - tail->next = new_elem;
> - tail = new_elem;
> -
> - //calculate support redefine
> - str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
> - if(NULL != str_support_redefine){
> - support_redefine = str2bol(str_support_redefine);
> - gsupport_redefine |= support_redefine;
> - hymem_free_memory(str_support_redefine);
> - }
> -
> - //add bootclasspath
> -
> - bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
> - if(NULL != bootclasspath){
> - bootclasspath_item = strtok(bootclasspath, " ");
> - while(NULL != bootclasspath_item){
> - check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
> - bootclasspath_item = strtok(NULL, " ");
> - }
> - hymem_free_memory(bootclasspath);
> - }
> - hymem_free_memory(lwrmanifest);
> - hymem_free_memory(manifest);
> - return 0;
> + PORT_ACCESS_FROM_JAVAVM(vm);
> + VMI_ACCESS_FROM_JAVAVM(vm);
> +
> + AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
> + char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
> + char *jar_name, *manifest;
> + char *options = NULL;
> + char *class_name, *bootclasspath, *str_support_redefine;
> + char *bootclasspath_item;
> + char *classpath;
> + char *classpath_cpy;
> + int support_redefine = 0;
> + char *pos;
> + char *lwrmanifest;
> +
> + strcpy(agent_cpy, agent);
> + //parse jar name and options
> + pos = strchr(agent_cpy, '=');
> + if(pos>0){
> + *pos++ = 0;
> + options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
> + strcpy(options, pos);
> + }
> + jar_name =agent_cpy;
> +
> + //read jar files, find manifest entry and read bytes
> + //read attributes(premain class, support redefine, bootclasspath)
> + manifest = Read_Manifest(vm,env, jar_name);
> + lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
> + strcpy(lwrmanifest,manifest);
> + strlower(lwrmanifest);
> +
> + //jar itself added to bootclasspath
> + check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
> + classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
> + strcpy(classpath_cpy,classpath);
> + strcat(classpath_cpy,";");
> + strcat(classpath_cpy,jar_name);
> + check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
> + hymem_free_memory(classpath_cpy);
> + hymem_free_memory(jar_name);
> +
> + //save options, save class name, add to agent list
> + class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
> + if(NULL == class_name){
> + hymem_free_memory(lwrmanifest);
> + hymem_free_memory(manifest);
> + (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
> + }
> + new_elem->option = options;
> + new_elem->class_name = class_name;
> + new_elem->next = NULL;
> + tail->next = new_elem;
> + tail = new_elem;
> +
> + //calculate support redefine
> + str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
> + if(NULL != str_support_redefine){
> + support_redefine = str2bol(str_support_redefine);
> + gsupport_redefine |= support_redefine;
> + hymem_free_memory(str_support_redefine);
> + }
> +
> + //add bootclasspath
> +
> + bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
> + if(NULL != bootclasspath){
> + bootclasspath_item = strtok(bootclasspath, " ");
> + while(NULL != bootclasspath_item){
> + check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
> + bootclasspath_item = strtok(NULL, " ");
> + }
> + hymem_free_memory(bootclasspath);
> + }
> + hymem_free_memory(lwrmanifest);
> + hymem_free_memory(manifest);
> + return 0;
> }
>
> -JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
> - PORT_ACCESS_FROM_JAVAVM(vm);
> - VMI_ACCESS_FROM_JAVAVM(vm);
> - jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
> - if(JNI_OK != err){
> - return err;
> - }
> -
> - if(!gdata){
> - jvmtiCapabilities capabilities;
> - jvmtiError jvmti_err;
> - jvmtiEventCallbacks callbacks;
> - JNIEnv *env = NULL;
> - static jvmtiEnv *jvmti;
> -
> - gdata = hymem_allocate_memory(sizeof(AgentData));
> -
> - //get jvmti environment
> - err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
> - if(JNI_OK != err){
> - return err;
> - }
> - gdata->jvmti = jvmti;
> -
> - //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
> - memset(&capabilities, 0, sizeof(capabilities));
> - capabilities.can_generate_all_class_hook_events=1;
> - capabilities.can_redefine_classes = 1;
> - //FIXME VM doesnot support the capbility right now.
> - //capabilities.can_redefine_any_class = 1;
> - jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
> - check_jvmti_error(env, jvmti_err,
> - "Cannot add JVMTI capabilities.");
> -
> - //set events callback function
> - (void)memset(&callbacks, 0, sizeof(callbacks));
> - callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
> - callbacks.VMInit = &callbackVMInit;
> - jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
> -
> - //enable classfileloadhook event
> - jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
> - }
> -
> - return Parse_Options(vm,jnienv, gdata->jvmti,options);
> +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
> + PORT_ACCESS_FROM_JAVAVM(vm);
> + VMI_ACCESS_FROM_JAVAVM(vm);
> + jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
> + if(JNI_OK != err){
> + return err;
> + }
> +
> + if(!gdata){
> + jvmtiCapabilities capabilities;
> + jvmtiError jvmti_err;
> + jvmtiEventCallbacks callbacks;
> + JNIEnv *env = NULL;
> + static jvmtiEnv *jvmti;
> +
> + gdata = hymem_allocate_memory(sizeof(AgentData));
> +
> + //get jvmti environment
> + err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
> + if(JNI_OK != err){
> + return err;
> + }
> + gdata->jvmti = jvmti;
> +
> + //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
> + memset(&capabilities, 0, sizeof(capabilities));
> + capabilities.can_generate_all_class_hook_events=1;
> + capabilities.can_redefine_classes = 1;
> + //FIXME VM doesnot support the capbility right now.
> + //capabilities.can_redefine_any_class = 1;
> + jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
> + check_jvmti_error(env, jvmti_err,
> + "Cannot add JVMTI capabilities.");
> +
> + //set events callback function
> + (void)memset(&callbacks, 0, sizeof(callbacks));
> + callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
> + callbacks.VMInit = &callbackVMInit;
> + jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
> +
> + //enable classfileloadhook event
> + jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
> + }
> +
> + return Parse_Options(vm,jnienv, gdata->jvmti,options);
> }
>
> -JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
> - PORT_ACCESS_FROM_JAVAVM(vm);
> - VMI_ACCESS_FROM_JAVAVM(vm);
> - //free the resource here
> - if(gdata){
> - jvmtiEnv *jvmti = gdata->jvmti;
> - jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
> - if(err != JVMTI_ERROR_NONE) {
> - (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
> - }
> - hymem_free_memory(gdata);
> - gdata = NULL;
> - }
> - return;
> +JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
> + PORT_ACCESS_FROM_JAVAVM(vm);
> + VMI_ACCESS_FROM_JAVAVM(vm);
> + //free the resource here
> + if(gdata){
> + jvmtiEnv *jvmti = gdata->jvmti;
> + jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
> + if(err != JVMTI_ERROR_NONE) {
> + (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
> + }
> + hymem_free_memory(gdata);
> + gdata = NULL;
> + }
> + return;
> }
>
> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c?rev=881682&r1=881681&r2=881682&view=diff
> ==============================================================================
> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c (original)
> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c Wed Nov 18 06:19:58 2009
> @@ -1,13 +1,13 @@
> -/*
> +/*
> * Licensed to the Apache Software Foundation (ASF) under one or more
> * contributor license agreements. See the NOTICE file distributed with
> * this work for additional information regarding copyright ownership.
> * The ASF licenses this file to You under the Apache License, Version 2.0
> * (the "License"); you may not use this file except in compliance with
> * the License. You may obtain a copy of the License at
> - *
> + *
> * http://www.apache.org/licenses/LICENSE-2.0
> - *
> + *
> * Unless required by applicable law or agreed to in writing, software
> * distributed under the License is distributed on an "AS IS" BASIS,
> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> @@ -23,81 +23,81 @@
>
>
> void throw_exception(JNIEnv * env,jvmtiError err){
> - switch (err) {
> - case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "The environment does not possess the capability can_redefine_classes.");
> - return;
> - case JVMTI_ERROR_NULL_POINTER:
> - throwNewExceptionByName(env, "java/lang/NullPointerException",
> - "One of class_bytes is NULL.");
> - return;
> - case JVMTI_ERROR_UNMODIFIABLE_CLASS:
> - throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
> - "An element of class_definitions cannot be modified.");
> - return;
> - case JVMTI_ERROR_INVALID_CLASS:
> - throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
> - "An element of class_definitions is not a valid class.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_VERSION:
> - throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
> - "A new class file has a version number not supported by this VM.");
> - return;
> - case JVMTI_ERROR_INVALID_CLASS_FORMAT:
> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
> - "A new class file is malformed.");
> - return;
> - case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
> - throwNewExceptionByName(env, "java/lang/ClassCircularityError",
> - "The new class file definitions would lead to a circular definition.");
> - return;
> - case JVMTI_ERROR_FAILS_VERIFICATION:
> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
> - "The class bytes fail verification.");
> - return;
> - case JVMTI_ERROR_NAMES_DONT_MATCH:
> - throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
> - "The class name defined in a new class file is different from the name in the old class object.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A new class file requires adding a method.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A new class version changes a field.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A new class version does not declare a method declared in the old class version.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A new class version has different modifiers.");
> - return;
> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> - "A method in the new class version has different modifiers than its counterpart in the old class version.");
> - return;
> - default:
> - throwNewExceptionByName(env, "java/lang/InternalError",
> - "Unknown error during redefinition.");
> - }
> + switch (err) {
> + case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "The environment does not possess the capability can_redefine_classes.");
> + return;
> + case JVMTI_ERROR_NULL_POINTER:
> + throwNewExceptionByName(env, "java/lang/NullPointerException",
> + "One of class_bytes is NULL.");
> + return;
> + case JVMTI_ERROR_UNMODIFIABLE_CLASS:
> + throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
> + "An element of class_definitions cannot be modified.");
> + return;
> + case JVMTI_ERROR_INVALID_CLASS:
> + throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
> + "An element of class_definitions is not a valid class.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_VERSION:
> + throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
> + "A new class file has a version number not supported by this VM.");
> + return;
> + case JVMTI_ERROR_INVALID_CLASS_FORMAT:
> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
> + "A new class file is malformed.");
> + return;
> + case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
> + throwNewExceptionByName(env, "java/lang/ClassCircularityError",
> + "The new class file definitions would lead to a circular definition.");
> + return;
> + case JVMTI_ERROR_FAILS_VERIFICATION:
> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
> + "The class bytes fail verification.");
> + return;
> + case JVMTI_ERROR_NAMES_DONT_MATCH:
> + throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
> + "The class name defined in a new class file is different from the name in the old class object.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A new class file requires adding a method.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A new class version changes a field.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A new class version does not declare a method declared in the old class version.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A new class version has different modifiers.");
> + return;
> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
> + "A method in the new class version has different modifiers than its counterpart in the old class version.");
> + return;
> + default:
> + throwNewExceptionByName(env, "java/lang/InternalError",
> + "Unknown error during redefinition.");
> + }
> }
>
> void cleanup(JNIEnv* env, jvmtiClassDefinition *class_definitions, int filled_class_definitions){
> - PORT_ACCESS_FROM_ENV (env);
> - int i;
> - for(i = 0;i<filled_class_definitions;i++){
> - hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
> - }
> - hymem_free_memory(class_definitions);
> - return;
> + PORT_ACCESS_FROM_ENV (env);
> + int i;
> + for(i = 0;i<filled_class_definitions;i++){
> + hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
> + }
> + hymem_free_memory(class_definitions);
> + return;
> }
>
> /*
> @@ -105,32 +105,32 @@
> */
>
> jobjectArray extract_elements(JNIEnv *env, jvmtiEnv *jvmti, jint count, const jclass* classes_ptr){
> - jclass klass;
> - jobjectArray classes;
> - int index;
> - jvmtiError err;
> -
> - //get the class of "java.lang.Class" in java language
> - klass= (*env)->FindClass(env, "java/lang/Class");
> - if(NULL == klass){
> - return NULL;
> - }
> -
> - //initiate the object array to return, fill in all elements with the same value
> - classes = (*env)->NewObjectArray(env, count, klass, NULL);
> - if(NULL == classes){
> - return NULL;
> - }
> -
> - //fill in the object array with right values
> - for(index=0; index<count; index++){
> - (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
> - }
> + jclass klass;
> + jobjectArray classes;
> + int index;
> + jvmtiError err;
> +
> + //get the class of "java.lang.Class" in java language
> + klass= (*env)->FindClass(env, "java/lang/Class");
> + if(NULL == klass){
> + return NULL;
> + }
> +
> + //initiate the object array to return, fill in all elements with the same value
> + classes = (*env)->NewObjectArray(env, count, klass, NULL);
> + if(NULL == classes){
> + return NULL;
> + }
> +
> + //fill in the object array with right values
> + for(index=0; index<count; index++){
> + (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
> + }
>
> - err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
> - check_jvmti_error(env, err, "Cannot deallocate memory.");
> + err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
> + check_jvmti_error(env, err, "Cannot deallocate memory.");
>
> - return classes;
> + return classes;
> }
>
> /*
> @@ -140,17 +140,17 @@
> */
> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getAllLoadedClasses
> (JNIEnv* env, jobject objThis){
> - jvmtiEnv* jvmti=gdata->jvmti;
> - jint count=0;
> - jclass* classes_ptr=NULL;
> - jobjectArray classes; //the object array to return
> -
> - jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
> - check_jvmti_error(env, err, "Cannot get loaded classes.");
> + jvmtiEnv* jvmti=gdata->jvmti;
> + jint count=0;
> + jclass* classes_ptr=NULL;
> + jobjectArray classes; //the object array to return
> +
> + jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
> + check_jvmti_error(env, err, "Cannot get loaded classes.");
>
> - classes = extract_elements(env, jvmti, count, classes_ptr);
> + classes = extract_elements(env, jvmti, count, classes_ptr);
>
> - return classes;
> + return classes;
> }
>
>
> @@ -161,17 +161,17 @@
> */
> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getInitiatedClasses
> (JNIEnv * env, jobject objThis, jobject loader){
> - jvmtiEnv* jvmti=gdata->jvmti;
> - jint count=0;
> - jclass* classes_ptr=NULL;
> - jobjectArray classes;
> + jvmtiEnv* jvmti=gdata->jvmti;
> + jint count=0;
> + jclass* classes_ptr=NULL;
> + jobjectArray classes;
>
> - jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
> - check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
> + jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
> + check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
>
> - classes = extract_elements(env, jvmti, count, classes_ptr);
> + classes = extract_elements(env, jvmti, count, classes_ptr);
>
> - return classes;
> + return classes;
> }
>
> /*
> @@ -181,11 +181,11 @@
> */
> JNIEXPORT jlong JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getObjectSize_1native
> (JNIEnv * env, jobject objThis, jobject objToSize){
> - jvmtiEnv *jvmti=gdata->jvmti;
> - jlong size=0l;
> - jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
> - check_jvmti_error(env, err, "Cannot get object size.");
> - return size;
> + jvmtiEnv *jvmti=gdata->jvmti;
> + jlong size=0l;
> + jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
> + check_jvmti_error(env, err, "Cannot get object size.");
> + return size;
> }
>
> /*
> @@ -195,84 +195,84 @@
> */
> JNIEXPORT void JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_redefineClasses_1native
> (JNIEnv * env, jobject objThis, jobjectArray javaClassDefArr){
> - PORT_ACCESS_FROM_ENV (env);
> - jvmtiEnv* jvmti=gdata->jvmti;
> - int err;
> - int index;
> - jmethodID method_get_class;
> - jmethodID method_get_data;
> - jsize length;
> - jvmtiClassDefinition *class_definitions;
> - int i=0;
> - jclass clz;
> - jmethodID method_clear;
> -
> - //locate the java methods needed by class definition data extraction
> - jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
> - if(NULL == class_ClassDefinition){
> - return;
> - }
> -
> - method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
> - if(NULL == method_get_data){
> - return;
> - }
> -
> - method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
> - if(NULL == method_get_class){
> - return;
> - }
> -
> - //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
> - length=(*env)->GetArrayLength(env, javaClassDefArr);
> - class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
> - if(NULL == class_definitions){
> - return;
> - }
> -
> - //extract class definition data from java array into native array
> - for(index=0; index<length; index++){
> - int class_byte_count;
> - jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
> - jbyteArray jclass_bytes;
> - jbyte* class_bytes;
> - jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
> - if (NULL == klass){
> - cleanup(env, class_definitions, index);
> - return;
> - }
> - jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
> - class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
> - class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
> - if(NULL == class_bytes){
> - cleanup(env, class_definitions, index);
> - return;
> - }
> - (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
> -
> - //construct a jvmtiClassDefinition element
> - class_definitions[index].klass=klass;
> - class_definitions[index].class_bytes=(unsigned char*)class_bytes;
> - class_definitions[index].class_byte_count=class_byte_count;
> - }
> -
> - //perform redefinition
> - err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
> -
> - if (JVMTI_ERROR_NONE!=err){
> - clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
> - method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
> - (*env)->CallVoidMethod(env,objThis,method_clear);
> - throw_exception(env,err);
> - }
> - //free memory
> - cleanup(env, class_definitions, length);
> - return;
> + PORT_ACCESS_FROM_ENV (env);
> + jvmtiEnv* jvmti=gdata->jvmti;
> + int err;
> + int index;
> + jmethodID method_get_class;
> + jmethodID method_get_data;
> + jsize length;
> + jvmtiClassDefinition *class_definitions;
> + int i=0;
> + jclass clz;
> + jmethodID method_clear;
> +
> + //locate the java methods needed by class definition data extraction
> + jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
> + if(NULL == class_ClassDefinition){
> + return;
> + }
> +
> + method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
> + if(NULL == method_get_data){
> + return;
> + }
> +
> + method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
> + if(NULL == method_get_class){
> + return;
> + }
> +
> + //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
> + length=(*env)->GetArrayLength(env, javaClassDefArr);
> + class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
> + if(NULL == class_definitions){
> + return;
> + }
> +
> + //extract class definition data from java array into native array
> + for(index=0; index<length; index++){
> + int class_byte_count;
> + jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
> + jbyteArray jclass_bytes;
> + jbyte* class_bytes;
> + jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
> + if (NULL == klass){
> + cleanup(env, class_definitions, index);
> + return;
> + }
> + jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
> + class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
> + class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
> + if(NULL == class_bytes){
> + cleanup(env, class_definitions, index);
> + return;
> + }
> + (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
> +
> + //construct a jvmtiClassDefinition element
> + class_definitions[index].klass=klass;
> + class_definitions[index].class_bytes=(unsigned char*)class_bytes;
> + class_definitions[index].class_byte_count=class_byte_count;
> + }
> +
> + //perform redefinition
> + err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
> +
> + if (JVMTI_ERROR_NONE!=err){
> + clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
> + method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
> + (*env)->CallVoidMethod(env,objThis,method_clear);
> + throw_exception(env,err);
> + }
> + //free memory
> + cleanup(env, class_definitions, length);
> + return;
> }
>
> void check_jvmti_error(JNIEnv *env, jvmtiError error, const char *msg){
> - if(error != JVMTI_ERROR_NONE){
> - (*env)->FatalError(env,msg);
> - }
> - return;
> + if(error != JVMTI_ERROR_NONE){
> + (*env)->FatalError(env,msg);
> + }
> + return;
> }
>
>
>
Re: svn commit: r881682 - in /harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared:
inst_agt.c instrument.c
Posted by Nathan Beyer <nd...@apache.org>.
Oh, whoops. Apparently my brain is only capable of handling binary
information - freeze = true.
On Wed, Nov 18, 2009 at 10:52 AM, Tim Ellison <t....@gmail.com> wrote:
> Nope, in feature freeze now, and code freeze after Friday this week.
>
> Tim
>
> On 18/Nov/2009 16:50, Nathan Beyer wrote:
>> Aren't we in a code freeze?
>>
>> On Wed, Nov 18, 2009 at 12:19 AM, <re...@apache.org> wrote:
>>> Author: regisxu
>>> Date: Wed Nov 18 06:19:58 2009
>>> New Revision: 881682
>>>
>>> URL: http://svn.apache.org/viewvc?rev=881682&view=rev
>>> Log:
>>> delete trailing whitespace, indent code, no functional changes.
>>>
>>> Modified:
>>> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
>>> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
>>>
>>> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
>>> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c?rev=881682&r1=881681&r2=881682&view=diff
>>> ==============================================================================
>>> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c (original)
>>> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c Wed Nov 18 06:19:58 2009
>>> @@ -1,13 +1,13 @@
>>> -/*
>>> +/*
>>> * Licensed to the Apache Software Foundation (ASF) under one or more
>>> * contributor license agreements. See the NOTICE file distributed with
>>> * this work for additional information regarding copyright ownership.
>>> * The ASF licenses this file to You under the Apache License, Version 2.0
>>> * (the "License"); you may not use this file except in compliance with
>>> * the License. You may obtain a copy of the License at
>>> - *
>>> + *
>>> * http://www.apache.org/licenses/LICENSE-2.0
>>> - *
>>> + *
>>> * Unless required by applicable law or agreed to in writing, software
>>> * distributed under the License is distributed on an "AS IS" BASIS,
>>> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>>> @@ -39,387 +39,387 @@
>>>
>>> //call back function for ClassLoad event
>>> void JNICALL callbackClassFileLoadHook(jvmtiEnv *jvmti_env,
>>> - JNIEnv* jni_env,
>>> - jclass class_being_redefined,
>>> - jobject loader,
>>> - const char* name,
>>> - jobject protection_domain,
>>> - jint class_data_len,
>>> - const unsigned char* class_data,
>>> - jint* new_class_data_len,
>>> - unsigned char** new_class_data){
>>> -
>>> - jclass inst_class = *(gdata->inst_class);
>>> - jbyteArray jnew_bytes = NULL;
>>> - jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
>>> - jmethodID transform_method = *(gdata->transform_method);
>>> - int name_len = strlen(name);
>>> - jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
>>> -
>>> - //construct java byteArray for old class data and class name
>>> - (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
>>> - (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
>>> -
>>> - //invoke transform method
>>> - jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
>>> -
>>> - //get transform result to native char array
>>> - if(0 != jnew_bytes){
>>> - *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
>>> - (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
>>> - *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
>>> - (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
>>> - }
>>> - return;
>>> + JNIEnv* jni_env,
>>> + jclass class_being_redefined,
>>> + jobject loader,
>>> + const char* name,
>>> + jobject protection_domain,
>>> + jint class_data_len,
>>> + const unsigned char* class_data,
>>> + jint* new_class_data_len,
>>> + unsigned char** new_class_data){
>>> +
>>> + jclass inst_class = *(gdata->inst_class);
>>> + jbyteArray jnew_bytes = NULL;
>>> + jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
>>> + jmethodID transform_method = *(gdata->transform_method);
>>> + int name_len = strlen(name);
>>> + jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
>>> +
>>> + //construct java byteArray for old class data and class name
>>> + (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
>>> + (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
>>> +
>>> + //invoke transform method
>>> + jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
>>> +
>>> + //get transform result to native char array
>>> + if(0 != jnew_bytes){
>>> + *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
>>> + (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
>>> + *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
>>> + (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
>>> + }
>>> + return;
>>> }
>>>
>>> //call back function for VM init event
>>> void JNICALL callbackVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread){
>>> - jmethodID constructor;
>>> - static jmethodID transform_method;
>>> - static jmethodID premain_method;
>>> - static jobject inst_obj;
>>> - static jclass inst_class;
>>> - jvmtiError err;
>>> - AgentList *elem;
>>> -
>>> - PORT_ACCESS_FROM_ENV (env);
>>> - inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> - if(NULL == inst_class){
>>> - (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> - return;
>>> - }
>>> - inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
>>> - gdata->inst_class = &inst_class;
>>> -
>>> - constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
>>> - if(NULL == constructor){
>>> - (*env)->FatalError(env,"constructor cannot be found.");
>>> - return;
>>> - }
>>> -
>>> - inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
>>> - if(NULL == inst_obj){
>>> - (*env)->FatalError(env,"object cannot be inited.");
>>> - return;
>>> - }
>>> -
>>> - inst_obj = (*env)->NewGlobalRef(env, inst_obj);
>>> - gdata->inst = &inst_obj;
>>> -
>>> - transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
>>> - if(NULL == transform_method){
>>> - (*env)->FatalError(env,"transform method cannot find.");
>>> - return;
>>> - }
>>> - gdata->transform_method = &transform_method;
>>> -
>>> - premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
>>> - if(NULL == premain_method){
>>> - (*env)->FatalError(env,"executePremain method cannot find.");
>>> - return;
>>> - }
>>> - gdata->premain_method = &premain_method;
>>> - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
>>> - check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
>>> -
>>> - //parse command options and run premain class here
>>> - if(tail == &list){
>>> - return;
>>> - }
>>> - for(elem = list.next; elem != NULL; elem = list.next){
>>> - char *agent_options = elem->option;
>>> - char *class_name = elem->class_name;
>>> - jbyteArray joptions=NULL, jclass_name;
>>> - if(class_name){
>>> - jclass_name = (*env)->NewByteArray(env, strlen(class_name));
>>> - (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
>>> - }else{
>>> - goto DEALLOCATE;
>>> - }
>>> - if(agent_options){
>>> - joptions = (*env)->NewByteArray(env, strlen(agent_options));
>>> - (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
>>> - }
>>> -
>>> - (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
>>> -DEALLOCATE:
>>> - list.next = elem->next;
>>> - hymem_free_memory(elem->class_name);
>>> - hymem_free_memory(elem->option);
>>> - hymem_free_memory(elem);
>>> - }
>>> - tail = &list;
>>> + jmethodID constructor;
>>> + static jmethodID transform_method;
>>> + static jmethodID premain_method;
>>> + static jobject inst_obj;
>>> + static jclass inst_class;
>>> + jvmtiError err;
>>> + AgentList *elem;
>>> +
>>> + PORT_ACCESS_FROM_ENV (env);
>>> + inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> + if(NULL == inst_class){
>>> + (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> + return;
>>> + }
>>> + inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
>>> + gdata->inst_class = &inst_class;
>>> +
>>> + constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
>>> + if(NULL == constructor){
>>> + (*env)->FatalError(env,"constructor cannot be found.");
>>> + return;
>>> + }
>>> +
>>> + inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
>>> + if(NULL == inst_obj){
>>> + (*env)->FatalError(env,"object cannot be inited.");
>>> + return;
>>> + }
>>> +
>>> + inst_obj = (*env)->NewGlobalRef(env, inst_obj);
>>> + gdata->inst = &inst_obj;
>>> +
>>> + transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
>>> + if(NULL == transform_method){
>>> + (*env)->FatalError(env,"transform method cannot find.");
>>> + return;
>>> + }
>>> + gdata->transform_method = &transform_method;
>>> +
>>> + premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
>>> + if(NULL == premain_method){
>>> + (*env)->FatalError(env,"executePremain method cannot find.");
>>> + return;
>>> + }
>>> + gdata->premain_method = &premain_method;
>>> + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
>>> + check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
>>> +
>>> + //parse command options and run premain class here
>>> + if(tail == &list){
>>> + return;
>>> + }
>>> + for(elem = list.next; elem != NULL; elem = list.next){
>>> + char *agent_options = elem->option;
>>> + char *class_name = elem->class_name;
>>> + jbyteArray joptions=NULL, jclass_name;
>>> + if(class_name){
>>> + jclass_name = (*env)->NewByteArray(env, strlen(class_name));
>>> + (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
>>> + }else{
>>> + goto DEALLOCATE;
>>> + }
>>> + if(agent_options){
>>> + joptions = (*env)->NewByteArray(env, strlen(agent_options));
>>> + (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
>>> + }
>>> +
>>> + (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
>>> + DEALLOCATE:
>>> + list.next = elem->next;
>>> + hymem_free_memory(elem->class_name);
>>> + hymem_free_memory(elem->option);
>>> + hymem_free_memory(elem);
>>> + }
>>> + tail = &list;
>>> }
>>>
>>> char* Read_Manifest(JavaVM *vm, JNIEnv *env,const char *jar_name){
>>> - I_32 retval;
>>> + I_32 retval;
>>> #ifndef HY_ZIP_API
>>> - HyZipFile zipFile;
>>> - HyZipEntry zipEntry;
>>> + HyZipFile zipFile;
>>> + HyZipEntry zipEntry;
>>> #else
>>> - VMIZipFile zipFile;
>>> - VMIZipEntry zipEntry;
>>> + VMIZipFile zipFile;
>>> + VMIZipEntry zipEntry;
>>> #endif
>>> - char *result;
>>> - int size = 0;
>>> - char errorMessage[1024];
>>> -
>>> - /* Reach for the VM interface */
>>> - VMI_ACCESS_FROM_JAVAVM(vm);
>>> - PORT_ACCESS_FROM_JAVAVM(vm);
>>> + char *result;
>>> + int size = 0;
>>> + char errorMessage[1024];
>>> +
>>> + /* Reach for the VM interface */
>>> + VMI_ACCESS_FROM_JAVAVM(vm);
>>> + PORT_ACCESS_FROM_JAVAVM(vm);
>>>
>>> #ifdef HY_ZIP_API
>>> - VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
>>> + VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
>>>
>>> #endif /* HY_ZIP_API */
>>> - /* open zip file */
>>> + /* open zip file */
>>> #ifndef HY_ZIP_API
>>> - retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
>>> + retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
>>> #else /* HY_ZIP_API */
>>> - retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
>>> + retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
>>> #endif /* HY_ZIP_API */
>>> - if(retval){
>>> - sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
>>> - (*env)->FatalError(env, errorMessage);
>>> - return NULL;
>>> - }
>>> + if(retval){
>>> + sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
>>> + (*env)->FatalError(env, errorMessage);
>>> + return NULL;
>>> + }
>>>
>>> - /* get manifest entry */
>>> + /* get manifest entry */
>>> #ifndef HY_ZIP_API
>>> - zip_initZipEntry(privatePortLibrary, &zipEntry);
>>> - retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
>>> + zip_initZipEntry(privatePortLibrary, &zipEntry);
>>> + retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
>>> #else /* HY_ZIP_API */
>>> - zipFuncs->zip_initZipEntry(VMI, &zipEntry);
>>> - retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
>>> + zipFuncs->zip_initZipEntry(VMI, &zipEntry);
>>> + retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
>>> #endif /* HY_ZIP_API */
>>> - if (retval) {
>>> + if (retval) {
>>> #ifndef HY_ZIP_API
>>> - zip_freeZipEntry(PORTLIB, &zipEntry);
>>> + zip_freeZipEntry(PORTLIB, &zipEntry);
>>> #else /* HY_ZIP_API */
>>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> #endif /* HY_ZIP_API */
>>> - sprintf(errorMessage,"failed to get entry: %d\n", retval);
>>> - (*env)->FatalError(env, errorMessage);
>>> - return NULL;
>>> - }
>>> -
>>> - /* read bytes */
>>> - size = zipEntry.uncompressedSize;
>>> - result = (char *)hymem_allocate_memory(size*sizeof(char));
>>> + sprintf(errorMessage,"failed to get entry: %d\n", retval);
>>> + (*env)->FatalError(env, errorMessage);
>>> + return NULL;
>>> + }
>>> +
>>> + /* read bytes */
>>> + size = zipEntry.uncompressedSize;
>>> + result = (char *)hymem_allocate_memory(size*sizeof(char));
>>> #ifndef HY_ZIP_API
>>> - retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
>>> + retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
>>> #else /* HY_ZIP_API */
>>> - retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
>>> + retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
>>> #endif /* HY_ZIP_API */
>>> - if(retval){
>>> + if(retval){
>>> #ifndef HY_ZIP_API
>>> - zip_freeZipEntry(PORTLIB, &zipEntry);
>>> + zip_freeZipEntry(PORTLIB, &zipEntry);
>>> #else /* HY_ZIP_API */
>>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> #endif /* HY_ZIP_API */
>>> - sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
>>> - (*env)->FatalError(env, errorMessage);
>>> - return NULL;
>>> - }
>>> + sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
>>> + (*env)->FatalError(env, errorMessage);
>>> + return NULL;
>>> + }
>>>
>>> - /* free resource */
>>> + /* free resource */
>>> #ifndef HY_ZIP_API
>>> - zip_freeZipEntry(privatePortLibrary, &zipEntry);
>>> - retval = zip_closeZipFile(privatePortLibrary, &zipFile);
>>> + zip_freeZipEntry(privatePortLibrary, &zipEntry);
>>> + retval = zip_closeZipFile(privatePortLibrary, &zipFile);
>>> #else /* HY_ZIP_API */
>>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> - retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
>>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>>> + retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
>>> #endif /* HY_ZIP_API */
>>> - if (retval) {
>>> - sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
>>> - (*env)->FatalError(env, errorMessage);
>>> - return NULL;
>>> - }
>>> - return result;
>>> + if (retval) {
>>> + sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
>>> + (*env)->FatalError(env, errorMessage);
>>> + return NULL;
>>> + }
>>> + return result;
>>> }
>>>
>>> char* read_attribute(JavaVM *vm, char *manifest,char *lwrmanifest, const char * target){
>>> - char *pos;
>>> - char *end;
>>> - char *value;
>>> - int length;
>>> + char *pos;
>>> + char *end;
>>> + char *value;
>>> + int length;
>>> PORT_ACCESS_FROM_JAVAVM(vm);
>>> -
>>> +
>>> if(NULL == strstr(lwrmanifest,target)){
>>> - return NULL;
>>> - }
>>> -
>>> + return NULL;
>>> + }
>>> +
>>> pos = manifest+ (strstr(lwrmanifest,target) - lwrmanifest);
>>> - pos += strlen(target)+2;//": "
>>> - end = strchr(pos, '\n');
>>> - if(NULL == end){
>>> - end = manifest + strlen(manifest);
>>> - }
>>> - /* in windows, has '\r\n' in the end of line, omit '\r' */
>>> - if (*(end - 1) == '\r'){
>>> - end--;
>>> - }
>>> - length = end - pos;
>>> -
>>> - value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
>>> - strncpy(value, pos, length);
>>> - *(value+length) = '\0';
>>> - return value;
>>> + pos += strlen(target)+2;//": "
>>> + end = strchr(pos, '\n');
>>> + if(NULL == end){
>>> + end = manifest + strlen(manifest);
>>> + }
>>> + /* in windows, has '\r\n' in the end of line, omit '\r' */
>>> + if (*(end - 1) == '\r'){
>>> + end--;
>>> + }
>>> + length = end - pos;
>>> +
>>> + value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
>>> + strncpy(value, pos, length);
>>> + *(value+length) = '\0';
>>> + return value;
>>> }
>>>
>>> char* strlower(char * str){
>>> - char *temp = str;
>>> - while((*temp = tolower(*temp)))
>>> - temp++;
>>> - return str;
>>> + char *temp = str;
>>> + while((*temp = tolower(*temp)))
>>> + temp++;
>>> + return str;
>>> }
>>>
>>> -int str2bol(char *str){
>>> - return 0 == strcmp("true", strlower(str));
>>> +int str2bol(char *str){
>>> + return 0 == strcmp("true", strlower(str));
>>> }
>>>
>>> jint Parse_Options(JavaVM *vm, JNIEnv *env, jvmtiEnv *jvmti, const char *agent){
>>> - PORT_ACCESS_FROM_JAVAVM(vm);
>>> - VMI_ACCESS_FROM_JAVAVM(vm);
>>> -
>>> - AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
>>> - char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
>>> - char *jar_name, *manifest;
>>> - char *options = NULL;
>>> - char *class_name, *bootclasspath, *str_support_redefine;
>>> - char *bootclasspath_item;
>>> - char *classpath;
>>> - char *classpath_cpy;
>>> - int support_redefine = 0;
>>> - char *pos;
>>> - char *lwrmanifest;
>>> -
>>> - strcpy(agent_cpy, agent);
>>> - //parse jar name and options
>>> - pos = strchr(agent_cpy, '=');
>>> - if(pos>0){
>>> - *pos++ = 0;
>>> - options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
>>> - strcpy(options, pos);
>>> - }
>>> - jar_name =agent_cpy;
>>> -
>>> - //read jar files, find manifest entry and read bytes
>>> - //read attributes(premain class, support redefine, bootclasspath)
>>> - manifest = Read_Manifest(vm,env, jar_name);
>>> - lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
>>> - strcpy(lwrmanifest,manifest);
>>> - strlower(lwrmanifest);
>>> -
>>> - //jar itself added to bootclasspath
>>> - check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
>>> - classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
>>> - strcpy(classpath_cpy,classpath);
>>> - strcat(classpath_cpy,";");
>>> - strcat(classpath_cpy,jar_name);
>>> - check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
>>> - hymem_free_memory(classpath_cpy);
>>> - hymem_free_memory(jar_name);
>>> -
>>> - //save options, save class name, add to agent list
>>> - class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
>>> - if(NULL == class_name){
>>> - hymem_free_memory(lwrmanifest);
>>> - hymem_free_memory(manifest);
>>> - (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
>>> - }
>>> - new_elem->option = options;
>>> - new_elem->class_name = class_name;
>>> - new_elem->next = NULL;
>>> - tail->next = new_elem;
>>> - tail = new_elem;
>>> -
>>> - //calculate support redefine
>>> - str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
>>> - if(NULL != str_support_redefine){
>>> - support_redefine = str2bol(str_support_redefine);
>>> - gsupport_redefine |= support_redefine;
>>> - hymem_free_memory(str_support_redefine);
>>> - }
>>> -
>>> - //add bootclasspath
>>> -
>>> - bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
>>> - if(NULL != bootclasspath){
>>> - bootclasspath_item = strtok(bootclasspath, " ");
>>> - while(NULL != bootclasspath_item){
>>> - check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
>>> - bootclasspath_item = strtok(NULL, " ");
>>> - }
>>> - hymem_free_memory(bootclasspath);
>>> - }
>>> - hymem_free_memory(lwrmanifest);
>>> - hymem_free_memory(manifest);
>>> - return 0;
>>> + PORT_ACCESS_FROM_JAVAVM(vm);
>>> + VMI_ACCESS_FROM_JAVAVM(vm);
>>> +
>>> + AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
>>> + char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
>>> + char *jar_name, *manifest;
>>> + char *options = NULL;
>>> + char *class_name, *bootclasspath, *str_support_redefine;
>>> + char *bootclasspath_item;
>>> + char *classpath;
>>> + char *classpath_cpy;
>>> + int support_redefine = 0;
>>> + char *pos;
>>> + char *lwrmanifest;
>>> +
>>> + strcpy(agent_cpy, agent);
>>> + //parse jar name and options
>>> + pos = strchr(agent_cpy, '=');
>>> + if(pos>0){
>>> + *pos++ = 0;
>>> + options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
>>> + strcpy(options, pos);
>>> + }
>>> + jar_name =agent_cpy;
>>> +
>>> + //read jar files, find manifest entry and read bytes
>>> + //read attributes(premain class, support redefine, bootclasspath)
>>> + manifest = Read_Manifest(vm,env, jar_name);
>>> + lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
>>> + strcpy(lwrmanifest,manifest);
>>> + strlower(lwrmanifest);
>>> +
>>> + //jar itself added to bootclasspath
>>> + check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
>>> + classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
>>> + strcpy(classpath_cpy,classpath);
>>> + strcat(classpath_cpy,";");
>>> + strcat(classpath_cpy,jar_name);
>>> + check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
>>> + hymem_free_memory(classpath_cpy);
>>> + hymem_free_memory(jar_name);
>>> +
>>> + //save options, save class name, add to agent list
>>> + class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
>>> + if(NULL == class_name){
>>> + hymem_free_memory(lwrmanifest);
>>> + hymem_free_memory(manifest);
>>> + (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
>>> + }
>>> + new_elem->option = options;
>>> + new_elem->class_name = class_name;
>>> + new_elem->next = NULL;
>>> + tail->next = new_elem;
>>> + tail = new_elem;
>>> +
>>> + //calculate support redefine
>>> + str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
>>> + if(NULL != str_support_redefine){
>>> + support_redefine = str2bol(str_support_redefine);
>>> + gsupport_redefine |= support_redefine;
>>> + hymem_free_memory(str_support_redefine);
>>> + }
>>> +
>>> + //add bootclasspath
>>> +
>>> + bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
>>> + if(NULL != bootclasspath){
>>> + bootclasspath_item = strtok(bootclasspath, " ");
>>> + while(NULL != bootclasspath_item){
>>> + check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
>>> + bootclasspath_item = strtok(NULL, " ");
>>> + }
>>> + hymem_free_memory(bootclasspath);
>>> + }
>>> + hymem_free_memory(lwrmanifest);
>>> + hymem_free_memory(manifest);
>>> + return 0;
>>> }
>>>
>>> -JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
>>> - PORT_ACCESS_FROM_JAVAVM(vm);
>>> - VMI_ACCESS_FROM_JAVAVM(vm);
>>> - jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
>>> - if(JNI_OK != err){
>>> - return err;
>>> - }
>>> -
>>> - if(!gdata){
>>> - jvmtiCapabilities capabilities;
>>> - jvmtiError jvmti_err;
>>> - jvmtiEventCallbacks callbacks;
>>> - JNIEnv *env = NULL;
>>> - static jvmtiEnv *jvmti;
>>> -
>>> - gdata = hymem_allocate_memory(sizeof(AgentData));
>>> -
>>> - //get jvmti environment
>>> - err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
>>> - if(JNI_OK != err){
>>> - return err;
>>> - }
>>> - gdata->jvmti = jvmti;
>>> -
>>> - //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
>>> - memset(&capabilities, 0, sizeof(capabilities));
>>> - capabilities.can_generate_all_class_hook_events=1;
>>> - capabilities.can_redefine_classes = 1;
>>> - //FIXME VM doesnot support the capbility right now.
>>> - //capabilities.can_redefine_any_class = 1;
>>> - jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
>>> - check_jvmti_error(env, jvmti_err,
>>> - "Cannot add JVMTI capabilities.");
>>> -
>>> - //set events callback function
>>> - (void)memset(&callbacks, 0, sizeof(callbacks));
>>> - callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
>>> - callbacks.VMInit = &callbackVMInit;
>>> - jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
>>> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
>>> -
>>> - //enable classfileloadhook event
>>> - jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
>>> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
>>> - }
>>> -
>>> - return Parse_Options(vm,jnienv, gdata->jvmti,options);
>>> +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
>>> + PORT_ACCESS_FROM_JAVAVM(vm);
>>> + VMI_ACCESS_FROM_JAVAVM(vm);
>>> + jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
>>> + if(JNI_OK != err){
>>> + return err;
>>> + }
>>> +
>>> + if(!gdata){
>>> + jvmtiCapabilities capabilities;
>>> + jvmtiError jvmti_err;
>>> + jvmtiEventCallbacks callbacks;
>>> + JNIEnv *env = NULL;
>>> + static jvmtiEnv *jvmti;
>>> +
>>> + gdata = hymem_allocate_memory(sizeof(AgentData));
>>> +
>>> + //get jvmti environment
>>> + err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
>>> + if(JNI_OK != err){
>>> + return err;
>>> + }
>>> + gdata->jvmti = jvmti;
>>> +
>>> + //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
>>> + memset(&capabilities, 0, sizeof(capabilities));
>>> + capabilities.can_generate_all_class_hook_events=1;
>>> + capabilities.can_redefine_classes = 1;
>>> + //FIXME VM doesnot support the capbility right now.
>>> + //capabilities.can_redefine_any_class = 1;
>>> + jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
>>> + check_jvmti_error(env, jvmti_err,
>>> + "Cannot add JVMTI capabilities.");
>>> +
>>> + //set events callback function
>>> + (void)memset(&callbacks, 0, sizeof(callbacks));
>>> + callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
>>> + callbacks.VMInit = &callbackVMInit;
>>> + jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
>>> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
>>> +
>>> + //enable classfileloadhook event
>>> + jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
>>> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
>>> + }
>>> +
>>> + return Parse_Options(vm,jnienv, gdata->jvmti,options);
>>> }
>>>
>>> -JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
>>> - PORT_ACCESS_FROM_JAVAVM(vm);
>>> - VMI_ACCESS_FROM_JAVAVM(vm);
>>> - //free the resource here
>>> - if(gdata){
>>> - jvmtiEnv *jvmti = gdata->jvmti;
>>> - jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
>>> - if(err != JVMTI_ERROR_NONE) {
>>> - (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
>>> - }
>>> - hymem_free_memory(gdata);
>>> - gdata = NULL;
>>> - }
>>> - return;
>>> +JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
>>> + PORT_ACCESS_FROM_JAVAVM(vm);
>>> + VMI_ACCESS_FROM_JAVAVM(vm);
>>> + //free the resource here
>>> + if(gdata){
>>> + jvmtiEnv *jvmti = gdata->jvmti;
>>> + jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
>>> + if(err != JVMTI_ERROR_NONE) {
>>> + (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
>>> + }
>>> + hymem_free_memory(gdata);
>>> + gdata = NULL;
>>> + }
>>> + return;
>>> }
>>>
>>> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
>>> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c?rev=881682&r1=881681&r2=881682&view=diff
>>> ==============================================================================
>>> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c (original)
>>> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c Wed Nov 18 06:19:58 2009
>>> @@ -1,13 +1,13 @@
>>> -/*
>>> +/*
>>> * Licensed to the Apache Software Foundation (ASF) under one or more
>>> * contributor license agreements. See the NOTICE file distributed with
>>> * this work for additional information regarding copyright ownership.
>>> * The ASF licenses this file to You under the Apache License, Version 2.0
>>> * (the "License"); you may not use this file except in compliance with
>>> * the License. You may obtain a copy of the License at
>>> - *
>>> + *
>>> * http://www.apache.org/licenses/LICENSE-2.0
>>> - *
>>> + *
>>> * Unless required by applicable law or agreed to in writing, software
>>> * distributed under the License is distributed on an "AS IS" BASIS,
>>> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>>> @@ -23,81 +23,81 @@
>>>
>>>
>>> void throw_exception(JNIEnv * env,jvmtiError err){
>>> - switch (err) {
>>> - case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "The environment does not possess the capability can_redefine_classes.");
>>> - return;
>>> - case JVMTI_ERROR_NULL_POINTER:
>>> - throwNewExceptionByName(env, "java/lang/NullPointerException",
>>> - "One of class_bytes is NULL.");
>>> - return;
>>> - case JVMTI_ERROR_UNMODIFIABLE_CLASS:
>>> - throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
>>> - "An element of class_definitions cannot be modified.");
>>> - return;
>>> - case JVMTI_ERROR_INVALID_CLASS:
>>> - throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
>>> - "An element of class_definitions is not a valid class.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_VERSION:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
>>> - "A new class file has a version number not supported by this VM.");
>>> - return;
>>> - case JVMTI_ERROR_INVALID_CLASS_FORMAT:
>>> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
>>> - "A new class file is malformed.");
>>> - return;
>>> - case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
>>> - throwNewExceptionByName(env, "java/lang/ClassCircularityError",
>>> - "The new class file definitions would lead to a circular definition.");
>>> - return;
>>> - case JVMTI_ERROR_FAILS_VERIFICATION:
>>> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
>>> - "The class bytes fail verification.");
>>> - return;
>>> - case JVMTI_ERROR_NAMES_DONT_MATCH:
>>> - throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
>>> - "The class name defined in a new class file is different from the name in the old class object.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A new class file requires adding a method.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A new class version changes a field.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A new class version does not declare a method declared in the old class version.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A new class version has different modifiers.");
>>> - return;
>>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
>>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> - "A method in the new class version has different modifiers than its counterpart in the old class version.");
>>> - return;
>>> - default:
>>> - throwNewExceptionByName(env, "java/lang/InternalError",
>>> - "Unknown error during redefinition.");
>>> - }
>>> + switch (err) {
>>> + case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "The environment does not possess the capability can_redefine_classes.");
>>> + return;
>>> + case JVMTI_ERROR_NULL_POINTER:
>>> + throwNewExceptionByName(env, "java/lang/NullPointerException",
>>> + "One of class_bytes is NULL.");
>>> + return;
>>> + case JVMTI_ERROR_UNMODIFIABLE_CLASS:
>>> + throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
>>> + "An element of class_definitions cannot be modified.");
>>> + return;
>>> + case JVMTI_ERROR_INVALID_CLASS:
>>> + throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
>>> + "An element of class_definitions is not a valid class.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_VERSION:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
>>> + "A new class file has a version number not supported by this VM.");
>>> + return;
>>> + case JVMTI_ERROR_INVALID_CLASS_FORMAT:
>>> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
>>> + "A new class file is malformed.");
>>> + return;
>>> + case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
>>> + throwNewExceptionByName(env, "java/lang/ClassCircularityError",
>>> + "The new class file definitions would lead to a circular definition.");
>>> + return;
>>> + case JVMTI_ERROR_FAILS_VERIFICATION:
>>> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
>>> + "The class bytes fail verification.");
>>> + return;
>>> + case JVMTI_ERROR_NAMES_DONT_MATCH:
>>> + throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
>>> + "The class name defined in a new class file is different from the name in the old class object.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A new class file requires adding a method.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A new class version changes a field.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A new class version does not declare a method declared in the old class version.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A new class version has different modifiers.");
>>> + return;
>>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
>>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>>> + "A method in the new class version has different modifiers than its counterpart in the old class version.");
>>> + return;
>>> + default:
>>> + throwNewExceptionByName(env, "java/lang/InternalError",
>>> + "Unknown error during redefinition.");
>>> + }
>>> }
>>>
>>> void cleanup(JNIEnv* env, jvmtiClassDefinition *class_definitions, int filled_class_definitions){
>>> - PORT_ACCESS_FROM_ENV (env);
>>> - int i;
>>> - for(i = 0;i<filled_class_definitions;i++){
>>> - hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
>>> - }
>>> - hymem_free_memory(class_definitions);
>>> - return;
>>> + PORT_ACCESS_FROM_ENV (env);
>>> + int i;
>>> + for(i = 0;i<filled_class_definitions;i++){
>>> + hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
>>> + }
>>> + hymem_free_memory(class_definitions);
>>> + return;
>>> }
>>>
>>> /*
>>> @@ -105,32 +105,32 @@
>>> */
>>>
>>> jobjectArray extract_elements(JNIEnv *env, jvmtiEnv *jvmti, jint count, const jclass* classes_ptr){
>>> - jclass klass;
>>> - jobjectArray classes;
>>> - int index;
>>> - jvmtiError err;
>>> -
>>> - //get the class of "java.lang.Class" in java language
>>> - klass= (*env)->FindClass(env, "java/lang/Class");
>>> - if(NULL == klass){
>>> - return NULL;
>>> - }
>>> -
>>> - //initiate the object array to return, fill in all elements with the same value
>>> - classes = (*env)->NewObjectArray(env, count, klass, NULL);
>>> - if(NULL == classes){
>>> - return NULL;
>>> - }
>>> -
>>> - //fill in the object array with right values
>>> - for(index=0; index<count; index++){
>>> - (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
>>> - }
>>> + jclass klass;
>>> + jobjectArray classes;
>>> + int index;
>>> + jvmtiError err;
>>> +
>>> + //get the class of "java.lang.Class" in java language
>>> + klass= (*env)->FindClass(env, "java/lang/Class");
>>> + if(NULL == klass){
>>> + return NULL;
>>> + }
>>> +
>>> + //initiate the object array to return, fill in all elements with the same value
>>> + classes = (*env)->NewObjectArray(env, count, klass, NULL);
>>> + if(NULL == classes){
>>> + return NULL;
>>> + }
>>> +
>>> + //fill in the object array with right values
>>> + for(index=0; index<count; index++){
>>> + (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
>>> + }
>>>
>>> - err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
>>> - check_jvmti_error(env, err, "Cannot deallocate memory.");
>>> + err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
>>> + check_jvmti_error(env, err, "Cannot deallocate memory.");
>>>
>>> - return classes;
>>> + return classes;
>>> }
>>>
>>> /*
>>> @@ -140,17 +140,17 @@
>>> */
>>> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getAllLoadedClasses
>>> (JNIEnv* env, jobject objThis){
>>> - jvmtiEnv* jvmti=gdata->jvmti;
>>> - jint count=0;
>>> - jclass* classes_ptr=NULL;
>>> - jobjectArray classes; //the object array to return
>>> -
>>> - jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
>>> - check_jvmti_error(env, err, "Cannot get loaded classes.");
>>> + jvmtiEnv* jvmti=gdata->jvmti;
>>> + jint count=0;
>>> + jclass* classes_ptr=NULL;
>>> + jobjectArray classes; //the object array to return
>>> +
>>> + jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
>>> + check_jvmti_error(env, err, "Cannot get loaded classes.");
>>>
>>> - classes = extract_elements(env, jvmti, count, classes_ptr);
>>> + classes = extract_elements(env, jvmti, count, classes_ptr);
>>>
>>> - return classes;
>>> + return classes;
>>> }
>>>
>>>
>>> @@ -161,17 +161,17 @@
>>> */
>>> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getInitiatedClasses
>>> (JNIEnv * env, jobject objThis, jobject loader){
>>> - jvmtiEnv* jvmti=gdata->jvmti;
>>> - jint count=0;
>>> - jclass* classes_ptr=NULL;
>>> - jobjectArray classes;
>>> + jvmtiEnv* jvmti=gdata->jvmti;
>>> + jint count=0;
>>> + jclass* classes_ptr=NULL;
>>> + jobjectArray classes;
>>>
>>> - jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
>>> - check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
>>> + jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
>>> + check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
>>>
>>> - classes = extract_elements(env, jvmti, count, classes_ptr);
>>> + classes = extract_elements(env, jvmti, count, classes_ptr);
>>>
>>> - return classes;
>>> + return classes;
>>> }
>>>
>>> /*
>>> @@ -181,11 +181,11 @@
>>> */
>>> JNIEXPORT jlong JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getObjectSize_1native
>>> (JNIEnv * env, jobject objThis, jobject objToSize){
>>> - jvmtiEnv *jvmti=gdata->jvmti;
>>> - jlong size=0l;
>>> - jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
>>> - check_jvmti_error(env, err, "Cannot get object size.");
>>> - return size;
>>> + jvmtiEnv *jvmti=gdata->jvmti;
>>> + jlong size=0l;
>>> + jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
>>> + check_jvmti_error(env, err, "Cannot get object size.");
>>> + return size;
>>> }
>>>
>>> /*
>>> @@ -195,84 +195,84 @@
>>> */
>>> JNIEXPORT void JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_redefineClasses_1native
>>> (JNIEnv * env, jobject objThis, jobjectArray javaClassDefArr){
>>> - PORT_ACCESS_FROM_ENV (env);
>>> - jvmtiEnv* jvmti=gdata->jvmti;
>>> - int err;
>>> - int index;
>>> - jmethodID method_get_class;
>>> - jmethodID method_get_data;
>>> - jsize length;
>>> - jvmtiClassDefinition *class_definitions;
>>> - int i=0;
>>> - jclass clz;
>>> - jmethodID method_clear;
>>> -
>>> - //locate the java methods needed by class definition data extraction
>>> - jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
>>> - if(NULL == class_ClassDefinition){
>>> - return;
>>> - }
>>> -
>>> - method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
>>> - if(NULL == method_get_data){
>>> - return;
>>> - }
>>> -
>>> - method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
>>> - if(NULL == method_get_class){
>>> - return;
>>> - }
>>> -
>>> - //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
>>> - length=(*env)->GetArrayLength(env, javaClassDefArr);
>>> - class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
>>> - if(NULL == class_definitions){
>>> - return;
>>> - }
>>> -
>>> - //extract class definition data from java array into native array
>>> - for(index=0; index<length; index++){
>>> - int class_byte_count;
>>> - jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
>>> - jbyteArray jclass_bytes;
>>> - jbyte* class_bytes;
>>> - jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
>>> - if (NULL == klass){
>>> - cleanup(env, class_definitions, index);
>>> - return;
>>> - }
>>> - jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
>>> - class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
>>> - class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
>>> - if(NULL == class_bytes){
>>> - cleanup(env, class_definitions, index);
>>> - return;
>>> - }
>>> - (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
>>> -
>>> - //construct a jvmtiClassDefinition element
>>> - class_definitions[index].klass=klass;
>>> - class_definitions[index].class_bytes=(unsigned char*)class_bytes;
>>> - class_definitions[index].class_byte_count=class_byte_count;
>>> - }
>>> -
>>> - //perform redefinition
>>> - err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
>>> -
>>> - if (JVMTI_ERROR_NONE!=err){
>>> - clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> - method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
>>> - (*env)->CallVoidMethod(env,objThis,method_clear);
>>> - throw_exception(env,err);
>>> - }
>>> - //free memory
>>> - cleanup(env, class_definitions, length);
>>> - return;
>>> + PORT_ACCESS_FROM_ENV (env);
>>> + jvmtiEnv* jvmti=gdata->jvmti;
>>> + int err;
>>> + int index;
>>> + jmethodID method_get_class;
>>> + jmethodID method_get_data;
>>> + jsize length;
>>> + jvmtiClassDefinition *class_definitions;
>>> + int i=0;
>>> + jclass clz;
>>> + jmethodID method_clear;
>>> +
>>> + //locate the java methods needed by class definition data extraction
>>> + jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
>>> + if(NULL == class_ClassDefinition){
>>> + return;
>>> + }
>>> +
>>> + method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
>>> + if(NULL == method_get_data){
>>> + return;
>>> + }
>>> +
>>> + method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
>>> + if(NULL == method_get_class){
>>> + return;
>>> + }
>>> +
>>> + //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
>>> + length=(*env)->GetArrayLength(env, javaClassDefArr);
>>> + class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
>>> + if(NULL == class_definitions){
>>> + return;
>>> + }
>>> +
>>> + //extract class definition data from java array into native array
>>> + for(index=0; index<length; index++){
>>> + int class_byte_count;
>>> + jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
>>> + jbyteArray jclass_bytes;
>>> + jbyte* class_bytes;
>>> + jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
>>> + if (NULL == klass){
>>> + cleanup(env, class_definitions, index);
>>> + return;
>>> + }
>>> + jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
>>> + class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
>>> + class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
>>> + if(NULL == class_bytes){
>>> + cleanup(env, class_definitions, index);
>>> + return;
>>> + }
>>> + (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
>>> +
>>> + //construct a jvmtiClassDefinition element
>>> + class_definitions[index].klass=klass;
>>> + class_definitions[index].class_bytes=(unsigned char*)class_bytes;
>>> + class_definitions[index].class_byte_count=class_byte_count;
>>> + }
>>> +
>>> + //perform redefinition
>>> + err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
>>> +
>>> + if (JVMTI_ERROR_NONE!=err){
>>> + clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>>> + method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
>>> + (*env)->CallVoidMethod(env,objThis,method_clear);
>>> + throw_exception(env,err);
>>> + }
>>> + //free memory
>>> + cleanup(env, class_definitions, length);
>>> + return;
>>> }
>>>
>>> void check_jvmti_error(JNIEnv *env, jvmtiError error, const char *msg){
>>> - if(error != JVMTI_ERROR_NONE){
>>> - (*env)->FatalError(env,msg);
>>> - }
>>> - return;
>>> + if(error != JVMTI_ERROR_NONE){
>>> + (*env)->FatalError(env,msg);
>>> + }
>>> + return;
>>> }
>>>
>>>
>>>
>>
>
Re: svn commit: r881682 - in /harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared:
inst_agt.c instrument.c
Posted by Tim Ellison <t....@gmail.com>.
Nope, in feature freeze now, and code freeze after Friday this week.
Tim
On 18/Nov/2009 16:50, Nathan Beyer wrote:
> Aren't we in a code freeze?
>
> On Wed, Nov 18, 2009 at 12:19 AM, <re...@apache.org> wrote:
>> Author: regisxu
>> Date: Wed Nov 18 06:19:58 2009
>> New Revision: 881682
>>
>> URL: http://svn.apache.org/viewvc?rev=881682&view=rev
>> Log:
>> delete trailing whitespace, indent code, no functional changes.
>>
>> Modified:
>> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
>> harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
>>
>> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c
>> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c?rev=881682&r1=881681&r2=881682&view=diff
>> ==============================================================================
>> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c (original)
>> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/inst_agt.c Wed Nov 18 06:19:58 2009
>> @@ -1,13 +1,13 @@
>> -/*
>> +/*
>> * Licensed to the Apache Software Foundation (ASF) under one or more
>> * contributor license agreements. See the NOTICE file distributed with
>> * this work for additional information regarding copyright ownership.
>> * The ASF licenses this file to You under the Apache License, Version 2.0
>> * (the "License"); you may not use this file except in compliance with
>> * the License. You may obtain a copy of the License at
>> - *
>> + *
>> * http://www.apache.org/licenses/LICENSE-2.0
>> - *
>> + *
>> * Unless required by applicable law or agreed to in writing, software
>> * distributed under the License is distributed on an "AS IS" BASIS,
>> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>> @@ -39,387 +39,387 @@
>>
>> //call back function for ClassLoad event
>> void JNICALL callbackClassFileLoadHook(jvmtiEnv *jvmti_env,
>> - JNIEnv* jni_env,
>> - jclass class_being_redefined,
>> - jobject loader,
>> - const char* name,
>> - jobject protection_domain,
>> - jint class_data_len,
>> - const unsigned char* class_data,
>> - jint* new_class_data_len,
>> - unsigned char** new_class_data){
>> -
>> - jclass inst_class = *(gdata->inst_class);
>> - jbyteArray jnew_bytes = NULL;
>> - jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
>> - jmethodID transform_method = *(gdata->transform_method);
>> - int name_len = strlen(name);
>> - jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
>> -
>> - //construct java byteArray for old class data and class name
>> - (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
>> - (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
>> -
>> - //invoke transform method
>> - jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
>> -
>> - //get transform result to native char array
>> - if(0 != jnew_bytes){
>> - *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
>> - (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
>> - *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
>> - (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
>> - }
>> - return;
>> + JNIEnv* jni_env,
>> + jclass class_being_redefined,
>> + jobject loader,
>> + const char* name,
>> + jobject protection_domain,
>> + jint class_data_len,
>> + const unsigned char* class_data,
>> + jint* new_class_data_len,
>> + unsigned char** new_class_data){
>> +
>> + jclass inst_class = *(gdata->inst_class);
>> + jbyteArray jnew_bytes = NULL;
>> + jbyteArray jold_bytes = (*jni_env)->NewByteArray(jni_env, class_data_len);
>> + jmethodID transform_method = *(gdata->transform_method);
>> + int name_len = strlen(name);
>> + jbyteArray jname_bytes = (*jni_env)->NewByteArray(jni_env, name_len);
>> +
>> + //construct java byteArray for old class data and class name
>> + (*jni_env)->SetByteArrayRegion(jni_env, jold_bytes, 0, class_data_len, (jbyte *)class_data);
>> + (*jni_env)->SetByteArrayRegion(jni_env, jname_bytes, 0, name_len, (jbyte *)name);
>> +
>> + //invoke transform method
>> + jnew_bytes = (jbyteArray)(*jni_env)->CallObjectMethod(jni_env, *(gdata->inst), transform_method, loader, jname_bytes, class_being_redefined, protection_domain, jold_bytes);
>> +
>> + //get transform result to native char array
>> + if(0 != jnew_bytes){
>> + *new_class_data_len = (*jni_env)->GetArrayLength(jni_env, jnew_bytes);
>> + (*jvmti_env)->Allocate(jvmti_env, *new_class_data_len, new_class_data);
>> + *new_class_data = (*jni_env)->GetPrimitiveArrayCritical(jni_env, jnew_bytes, JNI_FALSE);
>> + (*jni_env)->ReleasePrimitiveArrayCritical(jni_env, jnew_bytes, *new_class_data, 0);
>> + }
>> + return;
>> }
>>
>> //call back function for VM init event
>> void JNICALL callbackVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread){
>> - jmethodID constructor;
>> - static jmethodID transform_method;
>> - static jmethodID premain_method;
>> - static jobject inst_obj;
>> - static jclass inst_class;
>> - jvmtiError err;
>> - AgentList *elem;
>> -
>> - PORT_ACCESS_FROM_ENV (env);
>> - inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>> - if(NULL == inst_class){
>> - (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
>> - return;
>> - }
>> - inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
>> - gdata->inst_class = &inst_class;
>> -
>> - constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
>> - if(NULL == constructor){
>> - (*env)->FatalError(env,"constructor cannot be found.");
>> - return;
>> - }
>> -
>> - inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
>> - if(NULL == inst_obj){
>> - (*env)->FatalError(env,"object cannot be inited.");
>> - return;
>> - }
>> -
>> - inst_obj = (*env)->NewGlobalRef(env, inst_obj);
>> - gdata->inst = &inst_obj;
>> -
>> - transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
>> - if(NULL == transform_method){
>> - (*env)->FatalError(env,"transform method cannot find.");
>> - return;
>> - }
>> - gdata->transform_method = &transform_method;
>> -
>> - premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
>> - if(NULL == premain_method){
>> - (*env)->FatalError(env,"executePremain method cannot find.");
>> - return;
>> - }
>> - gdata->premain_method = &premain_method;
>> - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
>> - check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
>> -
>> - //parse command options and run premain class here
>> - if(tail == &list){
>> - return;
>> - }
>> - for(elem = list.next; elem != NULL; elem = list.next){
>> - char *agent_options = elem->option;
>> - char *class_name = elem->class_name;
>> - jbyteArray joptions=NULL, jclass_name;
>> - if(class_name){
>> - jclass_name = (*env)->NewByteArray(env, strlen(class_name));
>> - (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
>> - }else{
>> - goto DEALLOCATE;
>> - }
>> - if(agent_options){
>> - joptions = (*env)->NewByteArray(env, strlen(agent_options));
>> - (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
>> - }
>> -
>> - (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
>> -DEALLOCATE:
>> - list.next = elem->next;
>> - hymem_free_memory(elem->class_name);
>> - hymem_free_memory(elem->option);
>> - hymem_free_memory(elem);
>> - }
>> - tail = &list;
>> + jmethodID constructor;
>> + static jmethodID transform_method;
>> + static jmethodID premain_method;
>> + static jobject inst_obj;
>> + static jclass inst_class;
>> + jvmtiError err;
>> + AgentList *elem;
>> +
>> + PORT_ACCESS_FROM_ENV (env);
>> + inst_class = (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>> + if(NULL == inst_class){
>> + (*env)->FatalError(env,"class cannot find: org/apache/harmony/instrument/internal/InstrumentationImpl");
>> + return;
>> + }
>> + inst_class = (jclass)(*env)->NewGlobalRef(env, inst_class);
>> + gdata->inst_class = &inst_class;
>> +
>> + constructor = (*env)->GetMethodID(env, inst_class,"<init>", "(Z)V");
>> + if(NULL == constructor){
>> + (*env)->FatalError(env,"constructor cannot be found.");
>> + return;
>> + }
>> +
>> + inst_obj = (*env)->NewObject(env, inst_class, constructor, gsupport_redefine?JNI_TRUE:JNI_FALSE);
>> + if(NULL == inst_obj){
>> + (*env)->FatalError(env,"object cannot be inited.");
>> + return;
>> + }
>> +
>> + inst_obj = (*env)->NewGlobalRef(env, inst_obj);
>> + gdata->inst = &inst_obj;
>> +
>> + transform_method = (*env)->GetMethodID(env, inst_class, "transform", "(Ljava/lang/ClassLoader;[BLjava/lang/Class;Ljava/security/ProtectionDomain;[B)[B");
>> + if(NULL == transform_method){
>> + (*env)->FatalError(env,"transform method cannot find.");
>> + return;
>> + }
>> + gdata->transform_method = &transform_method;
>> +
>> + premain_method = (*env)->GetMethodID(env, inst_class, "executePremain", "([B[B)V");
>> + if(NULL == premain_method){
>> + (*env)->FatalError(env,"executePremain method cannot find.");
>> + return;
>> + }
>> + gdata->premain_method = &premain_method;
>> + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
>> + check_jvmti_error(env, err, "Cannot set JVMTI ClassFileLoadHook event notification mode.");
>> +
>> + //parse command options and run premain class here
>> + if(tail == &list){
>> + return;
>> + }
>> + for(elem = list.next; elem != NULL; elem = list.next){
>> + char *agent_options = elem->option;
>> + char *class_name = elem->class_name;
>> + jbyteArray joptions=NULL, jclass_name;
>> + if(class_name){
>> + jclass_name = (*env)->NewByteArray(env, strlen(class_name));
>> + (*env)->SetByteArrayRegion(env, jclass_name, 0, strlen(class_name), (jbyte*)class_name);
>> + }else{
>> + goto DEALLOCATE;
>> + }
>> + if(agent_options){
>> + joptions = (*env)->NewByteArray(env, strlen(agent_options));
>> + (*env)->SetByteArrayRegion(env, joptions, 0, strlen(agent_options), (jbyte*)agent_options);
>> + }
>> +
>> + (*env)->CallObjectMethod(env, *(gdata->inst), *(gdata->premain_method), jclass_name, joptions);
>> + DEALLOCATE:
>> + list.next = elem->next;
>> + hymem_free_memory(elem->class_name);
>> + hymem_free_memory(elem->option);
>> + hymem_free_memory(elem);
>> + }
>> + tail = &list;
>> }
>>
>> char* Read_Manifest(JavaVM *vm, JNIEnv *env,const char *jar_name){
>> - I_32 retval;
>> + I_32 retval;
>> #ifndef HY_ZIP_API
>> - HyZipFile zipFile;
>> - HyZipEntry zipEntry;
>> + HyZipFile zipFile;
>> + HyZipEntry zipEntry;
>> #else
>> - VMIZipFile zipFile;
>> - VMIZipEntry zipEntry;
>> + VMIZipFile zipFile;
>> + VMIZipEntry zipEntry;
>> #endif
>> - char *result;
>> - int size = 0;
>> - char errorMessage[1024];
>> -
>> - /* Reach for the VM interface */
>> - VMI_ACCESS_FROM_JAVAVM(vm);
>> - PORT_ACCESS_FROM_JAVAVM(vm);
>> + char *result;
>> + int size = 0;
>> + char errorMessage[1024];
>> +
>> + /* Reach for the VM interface */
>> + VMI_ACCESS_FROM_JAVAVM(vm);
>> + PORT_ACCESS_FROM_JAVAVM(vm);
>>
>> #ifdef HY_ZIP_API
>> - VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
>> + VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI);
>>
>> #endif /* HY_ZIP_API */
>> - /* open zip file */
>> + /* open zip file */
>> #ifndef HY_ZIP_API
>> - retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
>> + retval = zip_openZipFile(privatePortLibrary, (char *)jar_name, &zipFile, NULL);
>> #else /* HY_ZIP_API */
>> - retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
>> + retval = zipFuncs->zip_openZipFile(VMI, (char *)jar_name, &zipFile, 0);
>> #endif /* HY_ZIP_API */
>> - if(retval){
>> - sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
>> - (*env)->FatalError(env, errorMessage);
>> - return NULL;
>> - }
>> + if(retval){
>> + sprintf(errorMessage,"failed to open file:%s, %d\n", jar_name, retval);
>> + (*env)->FatalError(env, errorMessage);
>> + return NULL;
>> + }
>>
>> - /* get manifest entry */
>> + /* get manifest entry */
>> #ifndef HY_ZIP_API
>> - zip_initZipEntry(privatePortLibrary, &zipEntry);
>> - retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
>> + zip_initZipEntry(privatePortLibrary, &zipEntry);
>> + retval = zip_getZipEntry(privatePortLibrary, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", TRUE);
>> #else /* HY_ZIP_API */
>> - zipFuncs->zip_initZipEntry(VMI, &zipEntry);
>> - retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
>> + zipFuncs->zip_initZipEntry(VMI, &zipEntry);
>> + retval = zipFuncs->zip_getZipEntry(VMI, &zipFile, &zipEntry, "META-INF/MANIFEST.MF", ZIP_FLAG_READ_DATA_POINTER);
>> #endif /* HY_ZIP_API */
>> - if (retval) {
>> + if (retval) {
>> #ifndef HY_ZIP_API
>> - zip_freeZipEntry(PORTLIB, &zipEntry);
>> + zip_freeZipEntry(PORTLIB, &zipEntry);
>> #else /* HY_ZIP_API */
>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> #endif /* HY_ZIP_API */
>> - sprintf(errorMessage,"failed to get entry: %d\n", retval);
>> - (*env)->FatalError(env, errorMessage);
>> - return NULL;
>> - }
>> -
>> - /* read bytes */
>> - size = zipEntry.uncompressedSize;
>> - result = (char *)hymem_allocate_memory(size*sizeof(char));
>> + sprintf(errorMessage,"failed to get entry: %d\n", retval);
>> + (*env)->FatalError(env, errorMessage);
>> + return NULL;
>> + }
>> +
>> + /* read bytes */
>> + size = zipEntry.uncompressedSize;
>> + result = (char *)hymem_allocate_memory(size*sizeof(char));
>> #ifndef HY_ZIP_API
>> - retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
>> + retval = zip_getZipEntryData(privatePortLibrary, &zipFile, &zipEntry, (unsigned char*)result, size);
>> #else /* HY_ZIP_API */
>> - retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
>> + retval = zipFuncs->zip_getZipEntryData(VMI, &zipFile, &zipEntry, (unsigned char*)result, size);
>> #endif /* HY_ZIP_API */
>> - if(retval){
>> + if(retval){
>> #ifndef HY_ZIP_API
>> - zip_freeZipEntry(PORTLIB, &zipEntry);
>> + zip_freeZipEntry(PORTLIB, &zipEntry);
>> #else /* HY_ZIP_API */
>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> #endif /* HY_ZIP_API */
>> - sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
>> - (*env)->FatalError(env, errorMessage);
>> - return NULL;
>> - }
>> + sprintf(errorMessage,"failed to get bytes from zip entry, %d\n", zipEntry.extraFieldLength);
>> + (*env)->FatalError(env, errorMessage);
>> + return NULL;
>> + }
>>
>> - /* free resource */
>> + /* free resource */
>> #ifndef HY_ZIP_API
>> - zip_freeZipEntry(privatePortLibrary, &zipEntry);
>> - retval = zip_closeZipFile(privatePortLibrary, &zipFile);
>> + zip_freeZipEntry(privatePortLibrary, &zipEntry);
>> + retval = zip_closeZipFile(privatePortLibrary, &zipFile);
>> #else /* HY_ZIP_API */
>> - zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> - retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
>> + zipFuncs->zip_freeZipEntry(VMI, &zipEntry);
>> + retval = zipFuncs->zip_closeZipFile(VMI, &zipFile);
>> #endif /* HY_ZIP_API */
>> - if (retval) {
>> - sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
>> - (*env)->FatalError(env, errorMessage);
>> - return NULL;
>> - }
>> - return result;
>> + if (retval) {
>> + sprintf(errorMessage,"failed to close zip file: %s, %d\n", jar_name, retval);
>> + (*env)->FatalError(env, errorMessage);
>> + return NULL;
>> + }
>> + return result;
>> }
>>
>> char* read_attribute(JavaVM *vm, char *manifest,char *lwrmanifest, const char * target){
>> - char *pos;
>> - char *end;
>> - char *value;
>> - int length;
>> + char *pos;
>> + char *end;
>> + char *value;
>> + int length;
>> PORT_ACCESS_FROM_JAVAVM(vm);
>> -
>> +
>> if(NULL == strstr(lwrmanifest,target)){
>> - return NULL;
>> - }
>> -
>> + return NULL;
>> + }
>> +
>> pos = manifest+ (strstr(lwrmanifest,target) - lwrmanifest);
>> - pos += strlen(target)+2;//": "
>> - end = strchr(pos, '\n');
>> - if(NULL == end){
>> - end = manifest + strlen(manifest);
>> - }
>> - /* in windows, has '\r\n' in the end of line, omit '\r' */
>> - if (*(end - 1) == '\r'){
>> - end--;
>> - }
>> - length = end - pos;
>> -
>> - value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
>> - strncpy(value, pos, length);
>> - *(value+length) = '\0';
>> - return value;
>> + pos += strlen(target)+2;//": "
>> + end = strchr(pos, '\n');
>> + if(NULL == end){
>> + end = manifest + strlen(manifest);
>> + }
>> + /* in windows, has '\r\n' in the end of line, omit '\r' */
>> + if (*(end - 1) == '\r'){
>> + end--;
>> + }
>> + length = end - pos;
>> +
>> + value = (char *)hymem_allocate_memory(sizeof(char)*(length+1));
>> + strncpy(value, pos, length);
>> + *(value+length) = '\0';
>> + return value;
>> }
>>
>> char* strlower(char * str){
>> - char *temp = str;
>> - while((*temp = tolower(*temp)))
>> - temp++;
>> - return str;
>> + char *temp = str;
>> + while((*temp = tolower(*temp)))
>> + temp++;
>> + return str;
>> }
>>
>> -int str2bol(char *str){
>> - return 0 == strcmp("true", strlower(str));
>> +int str2bol(char *str){
>> + return 0 == strcmp("true", strlower(str));
>> }
>>
>> jint Parse_Options(JavaVM *vm, JNIEnv *env, jvmtiEnv *jvmti, const char *agent){
>> - PORT_ACCESS_FROM_JAVAVM(vm);
>> - VMI_ACCESS_FROM_JAVAVM(vm);
>> -
>> - AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
>> - char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
>> - char *jar_name, *manifest;
>> - char *options = NULL;
>> - char *class_name, *bootclasspath, *str_support_redefine;
>> - char *bootclasspath_item;
>> - char *classpath;
>> - char *classpath_cpy;
>> - int support_redefine = 0;
>> - char *pos;
>> - char *lwrmanifest;
>> -
>> - strcpy(agent_cpy, agent);
>> - //parse jar name and options
>> - pos = strchr(agent_cpy, '=');
>> - if(pos>0){
>> - *pos++ = 0;
>> - options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
>> - strcpy(options, pos);
>> - }
>> - jar_name =agent_cpy;
>> -
>> - //read jar files, find manifest entry and read bytes
>> - //read attributes(premain class, support redefine, bootclasspath)
>> - manifest = Read_Manifest(vm,env, jar_name);
>> - lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
>> - strcpy(lwrmanifest,manifest);
>> - strlower(lwrmanifest);
>> -
>> - //jar itself added to bootclasspath
>> - check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
>> - classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
>> - strcpy(classpath_cpy,classpath);
>> - strcat(classpath_cpy,";");
>> - strcat(classpath_cpy,jar_name);
>> - check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
>> - hymem_free_memory(classpath_cpy);
>> - hymem_free_memory(jar_name);
>> -
>> - //save options, save class name, add to agent list
>> - class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
>> - if(NULL == class_name){
>> - hymem_free_memory(lwrmanifest);
>> - hymem_free_memory(manifest);
>> - (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
>> - }
>> - new_elem->option = options;
>> - new_elem->class_name = class_name;
>> - new_elem->next = NULL;
>> - tail->next = new_elem;
>> - tail = new_elem;
>> -
>> - //calculate support redefine
>> - str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
>> - if(NULL != str_support_redefine){
>> - support_redefine = str2bol(str_support_redefine);
>> - gsupport_redefine |= support_redefine;
>> - hymem_free_memory(str_support_redefine);
>> - }
>> -
>> - //add bootclasspath
>> -
>> - bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
>> - if(NULL != bootclasspath){
>> - bootclasspath_item = strtok(bootclasspath, " ");
>> - while(NULL != bootclasspath_item){
>> - check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
>> - bootclasspath_item = strtok(NULL, " ");
>> - }
>> - hymem_free_memory(bootclasspath);
>> - }
>> - hymem_free_memory(lwrmanifest);
>> - hymem_free_memory(manifest);
>> - return 0;
>> + PORT_ACCESS_FROM_JAVAVM(vm);
>> + VMI_ACCESS_FROM_JAVAVM(vm);
>> +
>> + AgentList *new_elem = (AgentList *)hymem_allocate_memory(sizeof(AgentList));
>> + char *agent_cpy = (char *)hymem_allocate_memory(sizeof(char)*(strlen(agent)+1));
>> + char *jar_name, *manifest;
>> + char *options = NULL;
>> + char *class_name, *bootclasspath, *str_support_redefine;
>> + char *bootclasspath_item;
>> + char *classpath;
>> + char *classpath_cpy;
>> + int support_redefine = 0;
>> + char *pos;
>> + char *lwrmanifest;
>> +
>> + strcpy(agent_cpy, agent);
>> + //parse jar name and options
>> + pos = strchr(agent_cpy, '=');
>> + if(pos>0){
>> + *pos++ = 0;
>> + options = (char *)hymem_allocate_memory(sizeof(char) * (strlen(pos)+1));
>> + strcpy(options, pos);
>> + }
>> + jar_name =agent_cpy;
>> +
>> + //read jar files, find manifest entry and read bytes
>> + //read attributes(premain class, support redefine, bootclasspath)
>> + manifest = Read_Manifest(vm,env, jar_name);
>> + lwrmanifest = (char *)hymem_allocate_memory(sizeof(char) * (strlen(manifest)+1));
>> + strcpy(lwrmanifest,manifest);
>> + strlower(lwrmanifest);
>> +
>> + //jar itself added to bootclasspath
>> + check_jvmti_error(env, (*jvmti)->GetSystemProperty(jvmti,"java.class.path",&classpath),"Failed to get classpath.");
>> + classpath_cpy = (char *)hymem_allocate_memory((sizeof(char)*(strlen(classpath)+strlen(jar_name)+2)));
>> + strcpy(classpath_cpy,classpath);
>> + strcat(classpath_cpy,";");
>> + strcat(classpath_cpy,jar_name);
>> + check_jvmti_error(env, (*jvmti)->SetSystemProperty(jvmti, "java.class.path",classpath_cpy),"Failed to set classpath.");
>> + hymem_free_memory(classpath_cpy);
>> + hymem_free_memory(jar_name);
>> +
>> + //save options, save class name, add to agent list
>> + class_name = read_attribute(vm, manifest, lwrmanifest,"premain-class");
>> + if(NULL == class_name){
>> + hymem_free_memory(lwrmanifest);
>> + hymem_free_memory(manifest);
>> + (*env)->FatalError(env,"Cannot find Premain-Class attribute.");
>> + }
>> + new_elem->option = options;
>> + new_elem->class_name = class_name;
>> + new_elem->next = NULL;
>> + tail->next = new_elem;
>> + tail = new_elem;
>> +
>> + //calculate support redefine
>> + str_support_redefine = read_attribute(vm, manifest, lwrmanifest,"can-redefine-classes");
>> + if(NULL != str_support_redefine){
>> + support_redefine = str2bol(str_support_redefine);
>> + gsupport_redefine |= support_redefine;
>> + hymem_free_memory(str_support_redefine);
>> + }
>> +
>> + //add bootclasspath
>> +
>> + bootclasspath = read_attribute(vm, manifest, lwrmanifest,"boot-class-path");
>> + if(NULL != bootclasspath){
>> + bootclasspath_item = strtok(bootclasspath, " ");
>> + while(NULL != bootclasspath_item){
>> + check_jvmti_error(env, (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, bootclasspath_item),"Failed to add bootstrap classpath.");
>> + bootclasspath_item = strtok(NULL, " ");
>> + }
>> + hymem_free_memory(bootclasspath);
>> + }
>> + hymem_free_memory(lwrmanifest);
>> + hymem_free_memory(manifest);
>> + return 0;
>> }
>>
>> -JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
>> - PORT_ACCESS_FROM_JAVAVM(vm);
>> - VMI_ACCESS_FROM_JAVAVM(vm);
>> - jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
>> - if(JNI_OK != err){
>> - return err;
>> - }
>> -
>> - if(!gdata){
>> - jvmtiCapabilities capabilities;
>> - jvmtiError jvmti_err;
>> - jvmtiEventCallbacks callbacks;
>> - JNIEnv *env = NULL;
>> - static jvmtiEnv *jvmti;
>> -
>> - gdata = hymem_allocate_memory(sizeof(AgentData));
>> -
>> - //get jvmti environment
>> - err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
>> - if(JNI_OK != err){
>> - return err;
>> - }
>> - gdata->jvmti = jvmti;
>> -
>> - //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
>> - memset(&capabilities, 0, sizeof(capabilities));
>> - capabilities.can_generate_all_class_hook_events=1;
>> - capabilities.can_redefine_classes = 1;
>> - //FIXME VM doesnot support the capbility right now.
>> - //capabilities.can_redefine_any_class = 1;
>> - jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
>> - check_jvmti_error(env, jvmti_err,
>> - "Cannot add JVMTI capabilities.");
>> -
>> - //set events callback function
>> - (void)memset(&callbacks, 0, sizeof(callbacks));
>> - callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
>> - callbacks.VMInit = &callbackVMInit;
>> - jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
>> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
>> -
>> - //enable classfileloadhook event
>> - jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
>> - check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
>> - }
>> -
>> - return Parse_Options(vm,jnienv, gdata->jvmti,options);
>> +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
>> + PORT_ACCESS_FROM_JAVAVM(vm);
>> + VMI_ACCESS_FROM_JAVAVM(vm);
>> + jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
>> + if(JNI_OK != err){
>> + return err;
>> + }
>> +
>> + if(!gdata){
>> + jvmtiCapabilities capabilities;
>> + jvmtiError jvmti_err;
>> + jvmtiEventCallbacks callbacks;
>> + JNIEnv *env = NULL;
>> + static jvmtiEnv *jvmti;
>> +
>> + gdata = hymem_allocate_memory(sizeof(AgentData));
>> +
>> + //get jvmti environment
>> + err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
>> + if(JNI_OK != err){
>> + return err;
>> + }
>> + gdata->jvmti = jvmti;
>> +
>> + //set prerequisite capabilities for classfileloadhook, redefine, and VMInit event
>> + memset(&capabilities, 0, sizeof(capabilities));
>> + capabilities.can_generate_all_class_hook_events=1;
>> + capabilities.can_redefine_classes = 1;
>> + //FIXME VM doesnot support the capbility right now.
>> + //capabilities.can_redefine_any_class = 1;
>> + jvmti_err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
>> + check_jvmti_error(env, jvmti_err,
>> + "Cannot add JVMTI capabilities.");
>> +
>> + //set events callback function
>> + (void)memset(&callbacks, 0, sizeof(callbacks));
>> + callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
>> + callbacks.VMInit = &callbackVMInit;
>> + jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
>> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");
>> +
>> + //enable classfileloadhook event
>> + jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
>> + check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
>> + }
>> +
>> + return Parse_Options(vm,jnienv, gdata->jvmti,options);
>> }
>>
>> -JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
>> - PORT_ACCESS_FROM_JAVAVM(vm);
>> - VMI_ACCESS_FROM_JAVAVM(vm);
>> - //free the resource here
>> - if(gdata){
>> - jvmtiEnv *jvmti = gdata->jvmti;
>> - jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
>> - if(err != JVMTI_ERROR_NONE) {
>> - (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
>> - }
>> - hymem_free_memory(gdata);
>> - gdata = NULL;
>> - }
>> - return;
>> +JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm){
>> + PORT_ACCESS_FROM_JAVAVM(vm);
>> + VMI_ACCESS_FROM_JAVAVM(vm);
>> + //free the resource here
>> + if(gdata){
>> + jvmtiEnv *jvmti = gdata->jvmti;
>> + jvmtiError err = (*jvmti)->DisposeEnvironment(jvmti);
>> + if(err != JVMTI_ERROR_NONE) {
>> + (*jnienv)->FatalError(jnienv,"Cannot dispose JVMTI environment.");
>> + }
>> + hymem_free_memory(gdata);
>> + gdata = NULL;
>> + }
>> + return;
>> }
>>
>> Modified: harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c
>> URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c?rev=881682&r1=881681&r2=881682&view=diff
>> ==============================================================================
>> --- harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c (original)
>> +++ harmony/enhanced/classlib/trunk/modules/instrument/src/main/native/instrument/shared/instrument.c Wed Nov 18 06:19:58 2009
>> @@ -1,13 +1,13 @@
>> -/*
>> +/*
>> * Licensed to the Apache Software Foundation (ASF) under one or more
>> * contributor license agreements. See the NOTICE file distributed with
>> * this work for additional information regarding copyright ownership.
>> * The ASF licenses this file to You under the Apache License, Version 2.0
>> * (the "License"); you may not use this file except in compliance with
>> * the License. You may obtain a copy of the License at
>> - *
>> + *
>> * http://www.apache.org/licenses/LICENSE-2.0
>> - *
>> + *
>> * Unless required by applicable law or agreed to in writing, software
>> * distributed under the License is distributed on an "AS IS" BASIS,
>> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>> @@ -23,81 +23,81 @@
>>
>>
>> void throw_exception(JNIEnv * env,jvmtiError err){
>> - switch (err) {
>> - case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "The environment does not possess the capability can_redefine_classes.");
>> - return;
>> - case JVMTI_ERROR_NULL_POINTER:
>> - throwNewExceptionByName(env, "java/lang/NullPointerException",
>> - "One of class_bytes is NULL.");
>> - return;
>> - case JVMTI_ERROR_UNMODIFIABLE_CLASS:
>> - throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
>> - "An element of class_definitions cannot be modified.");
>> - return;
>> - case JVMTI_ERROR_INVALID_CLASS:
>> - throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
>> - "An element of class_definitions is not a valid class.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_VERSION:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
>> - "A new class file has a version number not supported by this VM.");
>> - return;
>> - case JVMTI_ERROR_INVALID_CLASS_FORMAT:
>> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
>> - "A new class file is malformed.");
>> - return;
>> - case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
>> - throwNewExceptionByName(env, "java/lang/ClassCircularityError",
>> - "The new class file definitions would lead to a circular definition.");
>> - return;
>> - case JVMTI_ERROR_FAILS_VERIFICATION:
>> - throwNewExceptionByName(env, "java/lang/ClassFormatError",
>> - "The class bytes fail verification.");
>> - return;
>> - case JVMTI_ERROR_NAMES_DONT_MATCH:
>> - throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
>> - "The class name defined in a new class file is different from the name in the old class object.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A new class file requires adding a method.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A new class version changes a field.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A new class version does not declare a method declared in the old class version.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A new class version has different modifiers.");
>> - return;
>> - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
>> - throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> - "A method in the new class version has different modifiers than its counterpart in the old class version.");
>> - return;
>> - default:
>> - throwNewExceptionByName(env, "java/lang/InternalError",
>> - "Unknown error during redefinition.");
>> - }
>> + switch (err) {
>> + case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "The environment does not possess the capability can_redefine_classes.");
>> + return;
>> + case JVMTI_ERROR_NULL_POINTER:
>> + throwNewExceptionByName(env, "java/lang/NullPointerException",
>> + "One of class_bytes is NULL.");
>> + return;
>> + case JVMTI_ERROR_UNMODIFIABLE_CLASS:
>> + throwNewExceptionByName(env, "java/lang/instrument/UnmodifiableClassException",
>> + "An element of class_definitions cannot be modified.");
>> + return;
>> + case JVMTI_ERROR_INVALID_CLASS:
>> + throwNewExceptionByName(env, "java/lang/ClassNotFoundException",
>> + "An element of class_definitions is not a valid class.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_VERSION:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedClassVersionError",
>> + "A new class file has a version number not supported by this VM.");
>> + return;
>> + case JVMTI_ERROR_INVALID_CLASS_FORMAT:
>> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
>> + "A new class file is malformed.");
>> + return;
>> + case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
>> + throwNewExceptionByName(env, "java/lang/ClassCircularityError",
>> + "The new class file definitions would lead to a circular definition.");
>> + return;
>> + case JVMTI_ERROR_FAILS_VERIFICATION:
>> + throwNewExceptionByName(env, "java/lang/ClassFormatError",
>> + "The class bytes fail verification.");
>> + return;
>> + case JVMTI_ERROR_NAMES_DONT_MATCH:
>> + throwNewExceptionByName(env, "java/lang/NoClassDefFoundError",
>> + "The class name defined in a new class file is different from the name in the old class object.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A new class file requires adding a method.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A new class version changes a field.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A new class version does not declare a method declared in the old class version.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A new class version has different modifiers.");
>> + return;
>> + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
>> + throwNewExceptionByName(env, "java/lang/UnsupportedOperationException",
>> + "A method in the new class version has different modifiers than its counterpart in the old class version.");
>> + return;
>> + default:
>> + throwNewExceptionByName(env, "java/lang/InternalError",
>> + "Unknown error during redefinition.");
>> + }
>> }
>>
>> void cleanup(JNIEnv* env, jvmtiClassDefinition *class_definitions, int filled_class_definitions){
>> - PORT_ACCESS_FROM_ENV (env);
>> - int i;
>> - for(i = 0;i<filled_class_definitions;i++){
>> - hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
>> - }
>> - hymem_free_memory(class_definitions);
>> - return;
>> + PORT_ACCESS_FROM_ENV (env);
>> + int i;
>> + for(i = 0;i<filled_class_definitions;i++){
>> + hymem_free_memory((jbyte *)class_definitions[i].class_bytes);
>> + }
>> + hymem_free_memory(class_definitions);
>> + return;
>> }
>>
>> /*
>> @@ -105,32 +105,32 @@
>> */
>>
>> jobjectArray extract_elements(JNIEnv *env, jvmtiEnv *jvmti, jint count, const jclass* classes_ptr){
>> - jclass klass;
>> - jobjectArray classes;
>> - int index;
>> - jvmtiError err;
>> -
>> - //get the class of "java.lang.Class" in java language
>> - klass= (*env)->FindClass(env, "java/lang/Class");
>> - if(NULL == klass){
>> - return NULL;
>> - }
>> -
>> - //initiate the object array to return, fill in all elements with the same value
>> - classes = (*env)->NewObjectArray(env, count, klass, NULL);
>> - if(NULL == classes){
>> - return NULL;
>> - }
>> -
>> - //fill in the object array with right values
>> - for(index=0; index<count; index++){
>> - (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
>> - }
>> + jclass klass;
>> + jobjectArray classes;
>> + int index;
>> + jvmtiError err;
>> +
>> + //get the class of "java.lang.Class" in java language
>> + klass= (*env)->FindClass(env, "java/lang/Class");
>> + if(NULL == klass){
>> + return NULL;
>> + }
>> +
>> + //initiate the object array to return, fill in all elements with the same value
>> + classes = (*env)->NewObjectArray(env, count, klass, NULL);
>> + if(NULL == classes){
>> + return NULL;
>> + }
>> +
>> + //fill in the object array with right values
>> + for(index=0; index<count; index++){
>> + (*env)->SetObjectArrayElement(env, classes, index, classes_ptr[index]);
>> + }
>>
>> - err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
>> - check_jvmti_error(env, err, "Cannot deallocate memory.");
>> + err = (*jvmti)->Deallocate(jvmti,(unsigned char *)classes_ptr);
>> + check_jvmti_error(env, err, "Cannot deallocate memory.");
>>
>> - return classes;
>> + return classes;
>> }
>>
>> /*
>> @@ -140,17 +140,17 @@
>> */
>> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getAllLoadedClasses
>> (JNIEnv* env, jobject objThis){
>> - jvmtiEnv* jvmti=gdata->jvmti;
>> - jint count=0;
>> - jclass* classes_ptr=NULL;
>> - jobjectArray classes; //the object array to return
>> -
>> - jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
>> - check_jvmti_error(env, err, "Cannot get loaded classes.");
>> + jvmtiEnv* jvmti=gdata->jvmti;
>> + jint count=0;
>> + jclass* classes_ptr=NULL;
>> + jobjectArray classes; //the object array to return
>> +
>> + jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes_ptr);
>> + check_jvmti_error(env, err, "Cannot get loaded classes.");
>>
>> - classes = extract_elements(env, jvmti, count, classes_ptr);
>> + classes = extract_elements(env, jvmti, count, classes_ptr);
>>
>> - return classes;
>> + return classes;
>> }
>>
>>
>> @@ -161,17 +161,17 @@
>> */
>> JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getInitiatedClasses
>> (JNIEnv * env, jobject objThis, jobject loader){
>> - jvmtiEnv* jvmti=gdata->jvmti;
>> - jint count=0;
>> - jclass* classes_ptr=NULL;
>> - jobjectArray classes;
>> + jvmtiEnv* jvmti=gdata->jvmti;
>> + jint count=0;
>> + jclass* classes_ptr=NULL;
>> + jobjectArray classes;
>>
>> - jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
>> - check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
>> + jvmtiError err = (*jvmti)->GetClassLoaderClasses(jvmti, loader, &count, &classes_ptr);
>> + check_jvmti_error(env, err, "Cannot get loaded classes for this classloader.");
>>
>> - classes = extract_elements(env, jvmti, count, classes_ptr);
>> + classes = extract_elements(env, jvmti, count, classes_ptr);
>>
>> - return classes;
>> + return classes;
>> }
>>
>> /*
>> @@ -181,11 +181,11 @@
>> */
>> JNIEXPORT jlong JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_getObjectSize_1native
>> (JNIEnv * env, jobject objThis, jobject objToSize){
>> - jvmtiEnv *jvmti=gdata->jvmti;
>> - jlong size=0l;
>> - jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
>> - check_jvmti_error(env, err, "Cannot get object size.");
>> - return size;
>> + jvmtiEnv *jvmti=gdata->jvmti;
>> + jlong size=0l;
>> + jvmtiError err=(*jvmti)->GetObjectSize(jvmti, objToSize, &size);
>> + check_jvmti_error(env, err, "Cannot get object size.");
>> + return size;
>> }
>>
>> /*
>> @@ -195,84 +195,84 @@
>> */
>> JNIEXPORT void JNICALL Java_org_apache_harmony_instrument_internal_InstrumentationImpl_redefineClasses_1native
>> (JNIEnv * env, jobject objThis, jobjectArray javaClassDefArr){
>> - PORT_ACCESS_FROM_ENV (env);
>> - jvmtiEnv* jvmti=gdata->jvmti;
>> - int err;
>> - int index;
>> - jmethodID method_get_class;
>> - jmethodID method_get_data;
>> - jsize length;
>> - jvmtiClassDefinition *class_definitions;
>> - int i=0;
>> - jclass clz;
>> - jmethodID method_clear;
>> -
>> - //locate the java methods needed by class definition data extraction
>> - jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
>> - if(NULL == class_ClassDefinition){
>> - return;
>> - }
>> -
>> - method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
>> - if(NULL == method_get_data){
>> - return;
>> - }
>> -
>> - method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
>> - if(NULL == method_get_class){
>> - return;
>> - }
>> -
>> - //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
>> - length=(*env)->GetArrayLength(env, javaClassDefArr);
>> - class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
>> - if(NULL == class_definitions){
>> - return;
>> - }
>> -
>> - //extract class definition data from java array into native array
>> - for(index=0; index<length; index++){
>> - int class_byte_count;
>> - jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
>> - jbyteArray jclass_bytes;
>> - jbyte* class_bytes;
>> - jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
>> - if (NULL == klass){
>> - cleanup(env, class_definitions, index);
>> - return;
>> - }
>> - jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
>> - class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
>> - class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
>> - if(NULL == class_bytes){
>> - cleanup(env, class_definitions, index);
>> - return;
>> - }
>> - (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
>> -
>> - //construct a jvmtiClassDefinition element
>> - class_definitions[index].klass=klass;
>> - class_definitions[index].class_bytes=(unsigned char*)class_bytes;
>> - class_definitions[index].class_byte_count=class_byte_count;
>> - }
>> -
>> - //perform redefinition
>> - err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
>> -
>> - if (JVMTI_ERROR_NONE!=err){
>> - clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>> - method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
>> - (*env)->CallVoidMethod(env,objThis,method_clear);
>> - throw_exception(env,err);
>> - }
>> - //free memory
>> - cleanup(env, class_definitions, length);
>> - return;
>> + PORT_ACCESS_FROM_ENV (env);
>> + jvmtiEnv* jvmti=gdata->jvmti;
>> + int err;
>> + int index;
>> + jmethodID method_get_class;
>> + jmethodID method_get_data;
>> + jsize length;
>> + jvmtiClassDefinition *class_definitions;
>> + int i=0;
>> + jclass clz;
>> + jmethodID method_clear;
>> +
>> + //locate the java methods needed by class definition data extraction
>> + jclass class_ClassDefinition=(*env)->FindClass(env, "java/lang/instrument/ClassDefinition");
>> + if(NULL == class_ClassDefinition){
>> + return;
>> + }
>> +
>> + method_get_data=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClassFile", "()[B");
>> + if(NULL == method_get_data){
>> + return;
>> + }
>> +
>> + method_get_class=(*env)->GetMethodID(env, class_ClassDefinition, "getDefinitionClass", "()Ljava/lang/Class;");
>> + if(NULL == method_get_class){
>> + return;
>> + }
>> +
>> + //allocate memory for native jvmtiClassDefinition structs to hold class redefinition data
>> + length=(*env)->GetArrayLength(env, javaClassDefArr);
>> + class_definitions=(jvmtiClassDefinition*) hymem_allocate_memory(sizeof(jvmtiClassDefinition)*length);
>> + if(NULL == class_definitions){
>> + return;
>> + }
>> +
>> + //extract class definition data from java array into native array
>> + for(index=0; index<length; index++){
>> + int class_byte_count;
>> + jobject obj_ClassDefinition=(*env)->GetObjectArrayElement(env, javaClassDefArr, index);
>> + jbyteArray jclass_bytes;
>> + jbyte* class_bytes;
>> + jclass klass=(jclass)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_class);
>> + if (NULL == klass){
>> + cleanup(env, class_definitions, index);
>> + return;
>> + }
>> + jclass_bytes =(jbyteArray)(*env)->CallObjectMethod(env, obj_ClassDefinition, method_get_data);
>> + class_byte_count = (*env)->GetArrayLength(env, jclass_bytes);
>> + class_bytes = (jbyte *)hymem_allocate_memory(sizeof(jbyte)*class_byte_count);
>> + if(NULL == class_bytes){
>> + cleanup(env, class_definitions, index);
>> + return;
>> + }
>> + (*env)->GetByteArrayRegion(env,jclass_bytes,0,class_byte_count,class_bytes);
>> +
>> + //construct a jvmtiClassDefinition element
>> + class_definitions[index].klass=klass;
>> + class_definitions[index].class_bytes=(unsigned char*)class_bytes;
>> + class_definitions[index].class_byte_count=class_byte_count;
>> + }
>> +
>> + //perform redefinition
>> + err=(*jvmti)->RedefineClasses(jvmti, length, class_definitions);
>> +
>> + if (JVMTI_ERROR_NONE!=err){
>> + clz= (*env)->FindClass(env, "org/apache/harmony/instrument/internal/InstrumentationImpl");
>> + method_clear=(*env)->GetMethodID(env, clz, "clear", "()V");
>> + (*env)->CallVoidMethod(env,objThis,method_clear);
>> + throw_exception(env,err);
>> + }
>> + //free memory
>> + cleanup(env, class_definitions, length);
>> + return;
>> }
>>
>> void check_jvmti_error(JNIEnv *env, jvmtiError error, const char *msg){
>> - if(error != JVMTI_ERROR_NONE){
>> - (*env)->FatalError(env,msg);
>> - }
>> - return;
>> + if(error != JVMTI_ERROR_NONE){
>> + (*env)->FatalError(env,msg);
>> + }
>> + return;
>> }
>>
>>
>>
>