alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (JPLISAgent.h)

This example Java source code file (JPLISAgent.h) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

instrumentationimpl, jnicall, jnienv, jplis_init_error_agent_class_not_specified, jplis_init_error_allocation_failure, jplis_init_error_failure, jplis_instrumentimpl_constructor_methodname, jplis_instrumentimpl_constructor_methodsignature, jplisagent, jplisenvironment, jplisinitializationerror, jvmti_error_wrong_phase, jzz

The JPLISAgent.h Java example source code

/*
 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Copyright 2003 Wily Technology, Inc.
 */

#ifndef _JPLISAGENT_H_
#define _JPLISAGENT_H_

#include    <jni.h>
#include    <jvmti.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 *  The JPLISAgent manages the initialization all of the Java programming language Agents.
 *  It also supports the native method bridge between the JPLIS and the JVMTI.
 *  It maintains a single JVMTI Env that all JPL agents share.
 *  It parses command line requests and creates individual Java agents.
 */


/*
 *  Forward definitions
 */
struct  _JPLISAgent;

typedef struct _JPLISAgent        JPLISAgent;
typedef struct _JPLISEnvironment  JPLISEnvironment;


/* constants for class names and methods names and such
    these all must stay in sync with Java code & interfaces
*/
#define JPLIS_INSTRUMENTIMPL_CLASSNAME                      "sun/instrument/InstrumentationImpl"
#define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODNAME         "<init>"
#define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODSIGNATURE    "(JZZ)V"
#define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODNAME      "loadClassAndCallPremain"
#define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V"
#define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODNAME      "loadClassAndCallAgentmain"
#define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V"
#define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODNAME           "transform"
#define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODSIGNATURE      \
    "(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[BZ)[B"


/*
 *  Error messages
 */
#define JPLIS_ERRORMESSAGE_CANNOTSTART              "processing of -javaagent failed"


/*
 *  Our initialization errors
 */
typedef enum {
  JPLIS_INIT_ERROR_NONE,
  JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT,
  JPLIS_INIT_ERROR_FAILURE,
  JPLIS_INIT_ERROR_ALLOCATION_FAILURE,
  JPLIS_INIT_ERROR_AGENT_CLASS_NOT_SPECIFIED
} JPLISInitializationError;


struct _JPLISEnvironment {
    jvmtiEnv *              mJVMTIEnv;              /* the JVM TI environment */
    JPLISAgent *            mAgent;                 /* corresponding agent */
    jboolean                mIsRetransformer;       /* indicates if special environment */
};

struct _JPLISAgent {
    JavaVM *                mJVM;                   /* handle to the JVM */
    JPLISEnvironment        mNormalEnvironment;     /* for every thing but retransform stuff */
    JPLISEnvironment        mRetransformEnvironment;/* for retransform stuff only */
    jobject                 mInstrumentationImpl;   /* handle to the Instrumentation instance */
    jmethodID               mPremainCaller;         /* method on the InstrumentationImpl that does the premain stuff (cached to save lots of lookups) */
    jmethodID               mAgentmainCaller;       /* method on the InstrumentationImpl for agents loaded via attach mechanism */
    jmethodID               mTransform;             /* method on the InstrumentationImpl that does the class file transform */
    jboolean                mRedefineAvailable;     /* cached answer to "does this agent support redefine" */
    jboolean                mRedefineAdded;         /* indicates if can_redefine_classes capability has been added */
    jboolean                mNativeMethodPrefixAvailable; /* cached answer to "does this agent support prefixing" */
    jboolean                mNativeMethodPrefixAdded;     /* indicates if can_set_native_method_prefix capability has been added */
    char const *            mAgentClassName;        /* agent class name */
    char const *            mOptionsString;         /* -javaagent options string */
};

/*
 * JVMTI event handlers
 */

/* VMInit event handler. Installed during OnLoad, then removed during VMInit. */
extern void JNICALL
eventHandlerVMInit( jvmtiEnv *      jvmtienv,
                    JNIEnv *        jnienv,
                    jthread         thread);

/* ClassFileLoadHook event handler. Installed during VMInit, then left in place forever. */
extern void JNICALL
eventHandlerClassFileLoadHook(  jvmtiEnv *              jvmtienv,
                                JNIEnv *                jnienv,
                                jclass                  class_being_redefined,
                                jobject                 loader,
                                const char*             name,
                                jobject                 protectionDomain,
                                jint                    class_data_len,
                                const unsigned char*    class_data,
                                jint*                   new_class_data_len,
                                unsigned char**         new_class_data);

/*
 * Main entry points for the JPLIS JVMTI agent code
 */

/* looks up the  environment instance. returns null if there isn't one */
extern JPLISEnvironment *
getJPLISEnvironment(jvmtiEnv * jvmtienv);

/*  Creates a new JPLIS agent.
 *  Returns error if the agent cannot be created and initialized.
 *  The JPLISAgent* pointed to by agent_ptr is set to the new broker,
 *  or NULL if an error has occurred.
 */
extern JPLISInitializationError
createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr);

/* Adds can_redefine_classes capability */
extern void
addRedefineClassesCapability(JPLISAgent * agent);

/* Add the can_set_native_method_prefix capability */
extern void
addNativeMethodPrefixCapability(JPLISAgent * agent);

/* Add the can_maintain_original_method_order capability (for testing) */
extern void
addOriginalMethodOrderCapability(JPLISAgent * agent);


/* Our JPLIS agent is paralleled by a Java InstrumentationImpl instance.
 * This routine uses JNI to create and initialized the Java instance.
 * Returns true if it succeeds, false otherwise.
 */
extern jboolean
createInstrumentationImpl( JNIEnv *        jnienv,
                           JPLISAgent *    agent);


/* during OnLoad phase (command line parsing)
 *  record the parameters of -javaagent
 */
extern JPLISInitializationError
recordCommandLineData(  JPLISAgent *    agent,
                        const char *    agentClass,
                        const char *    optionsString );

/* Swaps the start phase event handlers out and the live phase event handlers in.
 * Also used in attach to enabled live phase event handlers.
 * Returns true if it succeeds, false otherwise.
 */
extern jboolean
setLivePhaseEventHandlers(  JPLISAgent * agent);

/* Loads the Java agent according to the already processed command line. For each,
 * loads the Java agent class, then calls the premain method.
 * Returns true if all Java agent classes are loaded and all premain methods complete with no exceptions,
 * false otherwise.
 */
extern jboolean
startJavaAgent( JPLISAgent *    agent,
                JNIEnv *        jnienv,
                const char *    classname,
                const char *    optionsString,
                jmethodID       agentMainMethod);


/* during VMInit processing
 *  this is how the invocation engine (callback wrapper) tells us to start up all the javaagents
 */
extern jboolean
processJavaStart(   JPLISAgent *    agent,
                    JNIEnv *        jnienv);

/* on an ongoing basis,
 *  this is how the invocation engine (callback wrapper) tells us to process a class file
 */
extern void
transformClassFile(             JPLISAgent *            agent,
                                JNIEnv *                jnienv,
                                jobject                 loader,
                                const char*             name,
                                jclass                  classBeingRedefined,
                                jobject                 protectionDomain,
                                jint                    class_data_len,
                                const unsigned char*    class_data,
                                jint*                   new_class_data_len,
                                unsigned char**         new_class_data,
                                jboolean                is_retransformer);

/* on an ongoing basis,
 *  Return the environment with the retransformation capability.
 *  Create it if it doesn't exist.
 */
extern jvmtiEnv *
retransformableEnvironment(JPLISAgent * agent);

/* on an ongoing basis,
 *  these are implementations of the Instrumentation services.
 *  Most are simple covers for JVMTI access services. These are the guts of the InstrumentationImpl
 *  native methods.
 */
extern jboolean
isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz);

extern jboolean
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent);

extern void
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);

extern void
retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes);

extern void
redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions);

extern jobjectArray
getAllLoadedClasses(JNIEnv * jnienv, JPLISAgent * agent);

extern jobjectArray
getInitiatedClasses(JNIEnv * jnienv, JPLISAgent * agent, jobject classLoader);

extern jlong
getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize);

extern void
appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile, jboolean isBootLoader);

extern void
setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefixArray,
                        jboolean isRetransformable);

#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv

/*
 * A set of macros for insulating the JLI method callers from
 * JVMTI_ERROR_WRONG_PHASE return codes.
 */

/* for a JLI method where "blob" is executed before simply returning */
#define check_phase_blob_ret(ret, blob)      \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        blob;                                \
        return;                              \
    }

/* for a JLI method where simply returning is benign */
#define check_phase_ret(ret)                 \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        return;                              \
    }

/* for a JLI method where returning zero (0) is benign */
#define check_phase_ret_0(ret)               \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        return 0;                            \
    }

/* for a JLI method where returning one (1) is benign */
#define check_phase_ret_1(ret)               \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        return 1;                            \
    }

/* for a case where a specific "blob" must be returned */
#define check_phase_ret_blob(ret, blob)      \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        return (blob);                       \
    }

/* for a JLI method where returning false is benign */
#define check_phase_ret_false(ret)           \
    if ((ret) == JVMTI_ERROR_WRONG_PHASE) {  \
        return (jboolean) 0;                 \
    }

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */


#endif

Other Java examples (source code examples)

Here is a short list of links related to this Java JPLISAgent.h source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.