//================================================================================================== // J a v a Interface // V i r t u a l _ m a c h i n e // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library 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 Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides a class to manipulate the Java Virtual Machine (JVM). */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "java/virtual_machine.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guJavaVirtualMachine #define guJavaVirtualMachine
// Headers //--------------------------------------------------------------------------------------- #include <bpp/java/jni.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef JAVA_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area javaVirtualMachine #define private_area javaVirtualMachine_private
namespace public_area { /*NAMESPACE*/ using namespace javaJni; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniJavaVirtualMachine has_initializer;
// Macrocommands //---------------------------------------------------------------------------------
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes class clVirtualMachine; //-----------------------------------------------------------------------------------Constant Types typedef const clVirtualMachine ctVirtualMachine; }
namespace private_area { #ifdef JNI_VERSION_1_2 typedef jyInteger (*tyCreateVMFunction)(jyVirtualMachine *,jyContext *,JavaVMInitArgs *); #else typedef jyInteger (*tyCreateVMFunction)(jyVirtualMachine *,jyContext *,JDK1_1InitArgs *); #endif }
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { function void getVirtualMachine(jyContext); function void loadVirtualMachine(void); function void unloadVirtualMachine(void); function ctVirtualMachine & virtualMachine(void); }
namespace private_area { void loadVirtualMachine(void); }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erClassPathParameter; /* The 'class_path' parameter is missing. */
/*ERROR*/ extern_error erJavaMaximumHeapParameter; /* The 'java_maximum_heap_size' parameter is missing. */
/*ERROR*/ extern_error erJavaMinimumHeapParameter; /* The 'java_minimum_heap_size' parameter is missing. */
/*ERROR*/ extern_error erJavaThreadAttaching; /* Can not attach the thread to the Java Virtual Machine. */
/*ERROR*/ extern_error erJavaThreadDetaching; /* Can not detach the thread from the Java Virtual Machine. */
/*ERROR*/ extern_error erVirtualMachineCreation; /* Can not create the Java Virtual Machine. */
/*ERROR*/ extern_error erVirtualMachineLocationParameter; /* The 'java_virtual_machine_location' parameter is missing. */
/*ERROR*/ extern_error erVirtualMachineNotLoaded; /* The Java Virtual Machine is not loaded. */ }
// Constants & Variables //------------------------------------------------------------------------- extern_static_constant(private,tyString,goClassPath,?); extern_static_constant(private,tyCardinal,goMaxHeapSize,?); extern_static_constant(private,tyCardinal,goMinHeapSize,?); extern_dynamic_constant(private,clString,goDummyLocationFlag,?); extern_dynamic_constant(private,clVirtualMachine,goVirtualMachine,?); extern_static_constant(private,clMutex,goMutex,?);
namespace private_area { extern function tyCreateVMFunction createVirtualMachine; }
// V i r t u a l M a c h i n e Interface //-------------------------------------------------------- namespace public_area { /*CLASS clVirtualMachine */ /* Represents a Java Virtual Machine. */ class clVirtualMachine { //-----------------------------------------------------------------------------------------Private private_property tyBoolean atEmbedded;
private_property clVirtualMachine & operator = (ctVirtualMachine &); private_property constructor clVirtualMachine(ctVirtualMachine &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clVirtualMachine */ /* Pointer to the virtual machine in JNI. */ read_only_attribute(jyVirtualMachine,atJniPointer,jniPointer);
public_property constructor clVirtualMachine(void); public_property constructor clVirtualMachine(jyContext); public_property destructor clVirtualMachine(void);
public_property void attachThread(void) const; public_property jyContext context(void) const; public_property void detachThread(void) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #endif |
//================================================================================================== // J a v a Implementation // V i r t u a l _ m a c h i n e // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library 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 Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "java/virtual_machine.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define JAVA_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/java/virtual_machine.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area javaVirtualMachine #define private_area javaVirtualMachine_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Java/Virtual_machine");
// Initialization //-------------------------------------------------------------------------------- #undef iniJavaVirtualMachine static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erClassPathParameter; static_error erJavaMaximumHeapParameter; static_error erJavaMinimumHeapParameter; static_error erJavaThreadAttaching; static_error erJavaThreadDetaching; static_error erVirtualMachineCreation; static_error erVirtualMachineLocationParameter; static_error erVirtualMachineNotLoaded; }
// Constants & Variables //------------------------------------------------------------------------- static_constant(tyString,goClassPath); static_constant(tyCardinal,goMaxHeapSize); static_constant(tyCardinal,goMinHeapSize); dynamic_constant(clDynamicLibrary,goLibrary); dynamic_constant(clVirtualMachine,goVirtualMachine); static_constant(clMutex,goMutex);
namespace private_area { function tyCreateVMFunction createVirtualMachine; }
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------GetVirtualMachine /*FUNCTION*/ /* Gets the Java Virtual Machine to which a context is attached. */ function void getVirtualMachine(jyContext agContext) { safe_yes ( private_area::goMutex.lock(); )
if (private_area::goVirtualMachine==nil) private_area::goVirtualMachine=new_object(clVirtualMachine(agContext));
safe_yes ( private_area::goMutex.release(); ) } //-------------------------------------------------------------------------------LoadVirtualMachine /*FUNCTION*/ /* Loads a Java Virtual Machine into memory if none is already there. */ function void loadVirtualMachine(void) { safe_yes ( private_area::goMutex.lock(); )
createThread((tyFunction)private_area::loadVirtualMachine,nil);
while (private_area::goVirtualMachine==nil) { suspendThread(1);
if (private_area::goVirtualMachine==nil) environment::out("Waiting Java Virtual Machine...",true,true); }
private_area::goVirtualMachine->attachThread(); safe_yes ( private_area::goMutex.release(); ) } //-----------------------------------------------------------------------------UnloadVirtualMachine /*FUNCTION*/ /* Unloads the Java Virtual Machine from memory, only if it was loaded using the function <CODE>loadVirtualMachine</CODE>. */ function void unloadVirtualMachine(void) { safe_yes ( private_area::goMutex.lock(); )
if (private_area::goVirtualMachine!=nil) { private_area::goVirtualMachine->detachThread(); delete_object(private_area::goVirtualMachine); private_area::goVirtualMachine=nil; }
safe_yes ( private_area::goMutex.release(); ) } //-----------------------------------------------------------------------------------VirtualMachine /*FUNCTION*/ /* Returns the Java Virtual Machine loaded into memory. Before any use of this function, <CODE>loadVirtualMachine</CODE> or <CODE>getVirtualMachine</CODE> has to be called. */ function ctVirtualMachine & virtualMachine(void) { method_name("virtualMachine");
safe_yes ( private_area::goMutex.lock(); )
if (private_area::goVirtualMachine==nil) { safe_yes ( private_area::goMutex.release(); ) send_error(erVirtualMachineNotLoaded); }
safe_yes ( private_area::goMutex.release(); ) return (*private_area::goVirtualMachine); } }
namespace private_area { //-------------------------------------------------------------------------------LoadVirtualMachine void loadVirtualMachine(void) { if (private_area::goVirtualMachine==nil) private_area::goVirtualMachine=new_object(clVirtualMachine());
while (private_area::goVirtualMachine!=nil) suspendThread(1); } }
// V i r t u a l M a c h i n e Implementation //--------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clVirtualMachine */ /* Builds a Java Virtual Machine from a dynamic library. */ property clVirtualMachine::clVirtualMachine(void) : atEmbedded(false),atJniPointer(nil) { method_name("virtualMachine::constructor");
if (private_area::createVirtualMachine==nil) send_error(erVirtualMachineCreation);
#ifdef JAVA_NATIVE_INTERFACE_YES jyContext lcContext = nil; jyInteger lcResult;
#ifdef JNI_VERSION_1_2 JavaVMInitArgs lcArguments; JavaVMOption lcOptionS[3]; clString lcString1; clString lcString2; clString lcString3;
lcString1=clString("-Djava.class.path=")+private_area::goClassPath; lcString2=clString("-Xms")+standard::string(private_area::goMinHeapSize)+"m"; lcString3=clString("-Xmx")+standard::string(private_area::goMaxHeapSize)+"m";
lcOptionS[0].optionString=lcString1.data(); lcOptionS[1].optionString=lcString2.data(); lcOptionS[2].optionString=lcString3.data();
lcArguments.version=JNI_VERSION_1_2; lcArguments.options=lcOptionS; lcArguments.nOptions=3; lcArguments.ignoreUnrecognized=java_false;
lcResult=private_area::createVirtualMachine(&atJniPointer,&lcContext,&lcArguments); #else JDK1_1InitArgs lcArguments; tyString lcClassPath;
lcClassPath=new_array(char,maximumPathLength()); lcArguments.version=JNI_VERSION_1_1; lcArguments.minHeapSize=private_area::goMinHeapSize*1024*1024; lcArguments.maxHeapSize=private_area::goMaxHeapSize*1024*1024; JNI_GetDefaultJavaVMInitArgs(&lcArguments);
bpp::low::string::copy(lcClassPath,lcArguments.classpath); bpp::low::string::concatenate(lcClassPath,pathSeparator()); bpp::low::string::concatenate(lcClassPath,private_area::goClassPath);
lcArguments.classpath=lcClassPath; lcResult=private_area::createVirtualMachine(&atJniPointer,&lcContext,&lcArguments); delete_array(lcClassPath); #endif
if (lcResult<0) send_error(erVirtualMachineCreation); atEmbedded=true; #else send_error(erVirtualMachineCreation); #endif } //--------------------------------------------------------------------------------------Constructor /*METHOD clVirtualMachine */ /* Builds the virtual machine attached to a given context. */ property clVirtualMachine::clVirtualMachine(jyContext agContext) : atEmbedded(false),atJniPointer(nil) { method_name("virtualMachine::constructor");
jni_yes ( if (agContext->GetJavaVM(&atJniPointer)<0) send_error(erVirtualMachineCreation); )
jni_no ( send_error(erVirtualMachineCreation); ) } //---------------------------------------------------------------------------------------Destructor /*METHOD clVirtualMachine */ /* Destructs the Java Virtual Machine. */ property clVirtualMachine::~clVirtualMachine(void) { jni_yes ( if (atEmbedded and atJniPointer!=nil) { if (context()->ExceptionOccurred()!=nil) { environment::nextLine(); environment::out("[!] Warning: A Java exception has been thrown.",true,true); environment::nextLine(); context()->ExceptionDescribe(); environment::nextLine(); }
//atJniPointer->DestroyJavaVM(); } ) } //-------------------------------------------------------------------------------------AttachThread /*METHOD clVirtualMachine */ /* Attaches the current thread to the virtual machine. */ property void clVirtualMachine::attachThread(void) const { method_name("virtualMachine::attachThread");
#ifdef JAVA_NATIVE_INTERFACE_YES jyInteger lcResult;
#ifdef JNI_VERSION_1_2 tyPointer lcContext = nil; #else jyContext lcContext = nil; #endif
lcResult=atJniPointer->AttachCurrentThread(&lcContext,nil); if (lcResult<0) send_error(erJavaThreadAttaching); #else send_error(erJavaThreadAttaching); #endif } //------------------------------------------------------------------------------------------Context /*METHOD clVirtualMachine */ /* Returns the Java context of the current thread. */ property jyContext clVirtualMachine::context(void) const { method_name("virtualMachine::context");
#ifdef JAVA_NATIVE_INTERFACE_YES jyInteger lcResult;
#ifdef JNI_VERSION_1_2 tyPointer lcContext = nil; #else jyContext lcContext = nil; #endif
lcResult=atJniPointer->AttachCurrentThread(&lcContext,nil); if (lcResult<0) send_error(erJavaThreadAttaching); return (reinterpret_cast<jyContext>(lcContext)); #else send_error(erJavaThreadAttaching); return (nil); #endif } //-------------------------------------------------------------------------------------DetachThread /*METHOD clVirtualMachine */ /* Detaches the current thread from the virtual machine. */ property void clVirtualMachine::detachThread(void) const { method_name("virtualMachine::detachThread");
jni_yes ( if (atJniPointer->DetachCurrentThread()<0) send_error(erJavaThreadDetaching); ) jni_no ( send_error(erJavaThreadDetaching); ) } }
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { clString lcLibraryName;
if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
jni_yes ( method_name("initializer::constructor"); )
erClassPathParameter.create("The 'class_path' parameter is missing."); erJavaMaximumHeapParameter.create("The 'java_maximum_heap_size' parameter is missing."); erJavaMinimumHeapParameter.create("The 'java_minimum_heap_size' parameter is missing."); erJavaThreadAttaching.create("Java - Can't attach the thread to the Java Virtual Machine."); erJavaThreadDetaching.create("Java - Can't detach the thread from the Java Virtual Machine."); erVirtualMachineCreation.create("Java - Can't create the Java Virtual Machine."); erVirtualMachineLocationParameter.create("The 'java_virtual_machine_location' parameter is missing."); erVirtualMachineNotLoaded.create("Java - The Java Virtual Machine isn't loaded.");
#ifdef JAVA_NATIVE_INTERFACE_YES if (environment::parameters().count(clString("class_path"))==0) send_error(erClassPathParameter);
if (environment::parameters().count(clString("java_virtual_machine_location"))==0) send_error(erVirtualMachineLocationParameter);
goClassPath = copy(environment::parameter(clString("class_path"))); lcLibraryName=environment::parameter(clString("java_virtual_machine_location")).data();
if (environment::parameters().count(clString("java_minimum_heap_size"))==0) send_error(erJavaMinimumHeapParameter);
if (environment::parameters().count(clString("java_maximum_heap_size"))==0) send_error(erJavaMaximumHeapParameter);
goMinHeapSize = cardinal(environment::parameter(clString("java_minimum_heap_size")).data()); goMaxHeapSize = cardinal(environment::parameter(clString("java_maximum_heap_size")).data());
#ifdef JAVA_VIRTUAL_MACHINE_DYNAMIC if (lcLibraryName=="dummy.dll") { goLibrary = nil; createVirtualMachine = nil; } else { goLibrary = new_object(clDynamicLibrary(lcLibraryName.data())); createVirtualMachine = (tyCreateVMFunction)goLibrary->symbol("JNI_CreateJavaVM"); } #else goLibrary = nil; createVirtualMachine = (tyCreateVMFunction)JNI_CreateJavaVM; #endif #endif
jni_no ( goClassPath = copy(clString(".")); goLibrary = nil; createVirtualMachine = nil; )
goVirtualMachine = nil; }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { try { environment::informTermination(goModuleName);
if (goVirtualMachine!=nil) delete_object(goVirtualMachine); delete_array(goClassPath); if (goLibrary!=nil) delete_object(goLibrary); }
initializer_catch; } }
// End //------------------------------------------------------------------------------------------- } |
|