--- a/javaruntimes/starterutils/src.linux/jvmstarterjni.cpp Tue May 11 16:07:20 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: This class is meant for starting the Linux JVM.
-*
-*/
-
-#include <string>
-#include <algorithm>
-
-#include "jvmstarterjni.h"
-
-#include "jvmargsmodifier.h"
-
-#include "runtimeexception.h"
-#include "logger.h"
-#include "javaoslayer.h"
-#include "dynamiclibloader.h"
-#include "javacommonutils.h"
-
-using namespace java::runtime;
-using namespace java::util;
-
-extern const wchar_t CLASS_PATH_SEPARATOR = L':';
-extern const char PATH_SEPARATOR_FROM = '\\';
-extern const char PATH_SEPARATOR_TO = '/';
-
-JvmStarter*
-JvmStarter::getJvmStarterInstance(const Configuration configuration,
- const std::wstring& indetifier)
-{
- JELOG2(EJavaRuntime);
- return new JvmStarterJni(configuration, indetifier);
-}
-
-JvmStarter*
-JvmStarter::getJvmStarterInstance()
-{
- JELOG2(EJavaRuntime);
- return new JvmStarterJni();
-}
-
-JvmStarterJni::JvmStarterJni()
-{
- JELOG2(EJavaRuntime);
-}
-
-JvmStarterJni::JvmStarterJni(const Configuration configuration,
- const std::wstring& indetifier)
-{
- JELOG2(EJavaRuntime);
- mConfiguration = configuration;
- mIdentifier = indetifier;
-
- // In Linux the binary root varies depending on the user.
- std::string rootStr;
- JavaOsLayer::getResRoot(rootStr, false);
- rootStr += "jsr/classes/common/";
- mExtensionPath.assign(rootStr.begin(), rootStr.end());
-}
-
-
-JvmStarterJni::~JvmStarterJni()
-{
- JELOG2(EJavaRuntime);
-}
-
-void JvmStarterJni::overrideOldHeapSize(int /*heapSize*/)
-{
- // Not supported by the JVM
- JELOG2(EJavaRuntime);
-}
-
-void JvmStarterJni::overrideNewHeapSize(int /*heapSize*/)
-{
- // Not supported by the JVM
- JELOG2(EJavaRuntime);
-}
-
-void JvmStarterJni::overrideNativeStackSize(int /*stackSize*/)
-{
- // Not supported by the JVM
- JELOG2(EJavaRuntime);
-}
-
-void JvmStarterJni::overrideJavaStackSize(int stackSize)
-{
- JELOG2(EJavaRuntime);
- std::wstring stackSizeStr = L"-Xss";
- stackSizeStr += JavaCommonUtils::intToWstring(stackSize);
- stackSizeStr += L"K";
- mJvmArgs.push_back(stackSizeStr);
-}
-
-int JvmStarterJni::startJvm()
-{
- JELOG2(EJavaRuntime);
-
- // Set mJvmArgs container to contain all the JVM args and set mAppAndArgs
- // to contain the main class and the arguments.
- completeArgumentContainers();
-
- // Give arguments to modifyJvmArguments for modification. Args
- // are modified if the default empty implementation has been overridden
- // by eclipsing the modifyJvmArguments dll.
- modifyJvmArguments(mIdentifier, mJvmArgs, mAppAndArgs);
-
- // Allocate space for the raw JVM args.
- int rawJvmArgumentCount = mJvmArgs.size();
- ScopedCharPointerArray rawJvmArgs(rawJvmArgumentCount);
-
- // Adding the JVM args. Main class and applcation arguments are handled
- // later.
- int ind = 0;
- for (JvmArgs_t::iterator jvmArgsIter = mJvmArgs.begin();
- jvmArgsIter!= mJvmArgs.end();
- ++jvmArgsIter)
- {
- // Do character conversion while adding the arguments.
- rawJvmArgs.get()[ind++] = JavaCommonUtils::wstringToUtf8(*jvmArgsIter);
- }
- return startJvmInSeparateThread(rawJvmArgumentCount, rawJvmArgs.get());
-}
-
-int JvmStarterJni::startJvm(int argc, char** argv)
-{
- JELOG2(EJavaRuntime);
- // Allocate space for the raw JVM args. This will contain only
- // JVM arguments. Main class and application arguments are handled
- // differently.
- ScopedCharPointerArray rawJvmArgs(argc);
-
- // Assuming that in the beginning of the list there are JVM arguments and
- // they start with '-'.
- bool handlingArguments = true;
-
- int argCount = 0;
- for (int i = 0; i < argc; i++)
- {
- if (argv[i][0] != '-') // codescanner::accessArrayElementWithoutCheck2
- {
- // First non JVM argument was found.
- handlingArguments = false;
- }
- if (handlingArguments)
- {
- if ((strcmp(argv[i], "-cp") == 0 || // codescanner::accessArrayElementWithoutCheck2
- strcmp(argv[i], "-classpath") == 0) && // codescanner::accessArrayElementWithoutCheck2
- (i + 1) < argc)
- {
- // There is class path available.
- std::string cp("-Djava.class.path=");
- cp += argv[i+1];
- i++;
- rawJvmArgs.get()[argCount] = strdup(cp.c_str());
- }
- else
- {
- // Normal JVM argument.
- rawJvmArgs.get()[argCount] = strdup(argv[i]); // codescanner::accessArrayElementWithoutCheck2
- }
- argCount++;
- }
- else
- {
- // The first non JVM argument can be considered as main class.
- // The rest of the arguments are arguments for the Java app.
- mAppAndArgs.push_back(JavaCommonUtils::utf8ToWstring(argv[i])); // codescanner::accessArrayElementWithoutCheck2
- }
- }
- return startJvmInSeparateThread(argCount, rawJvmArgs.get());
-}
-
-
-void* JvmStarterJni::javaThreadMain(void* arg)
-{
- JELOG2(EJavaRuntime);
- int result = -1;
- JvmStarterJni* jniStarter = (reinterpret_cast<JvmStarterJni*>(arg));
- try
- {
- result = jniStarter->startJvmImpl();
- }
- catch (RuntimeException& e)
- {
- ELOG1(EJavaRuntime, "JvmStarterJni::javaThreadMain() RuntimeException "
- "catched in VM thread. %s", e.toString().c_str());
- }
- catch (java::util::ExceptionBase& e)
- {
- ELOG1(EJavaRuntime, "JvmStarterJni::javaThreadMain() ExceptionBase "
- "catched in VM thread. %s", e.toString().c_str());
- }
- catch (std::exception& e)
- {
- ELOG1(EJavaRuntime, "JvmStarterJni::javaThreadMain() std::Exception "
- "catched in VM thread. %s", e.what());
- }
- return reinterpret_cast<void*>(result);
-}
-
-int JvmStarterJni::startJvmInSeparateThread(int argc, char** argv)
-{
- JELOG2(EJavaRuntime);
-
- // Store the argc and argv into member variables in order be avaliable
- // for the JVM starter thread.
- mArgCount = argc;
- mArgs = argv;
- // return startJvmImpl(); This could be used to start the JVM into same
- // thread.
- pthread_t threadId;
- void* result;
-
- // Create the JVM thread.
- pthread_create(&threadId, 0, javaThreadMain, this);
-
- // Wait until the thread has died.
- pthread_join(threadId, &result);
- return reinterpret_cast<int>(result);
-}
-
-
-int JvmStarterJni::startJvmImpl()
-{
- JELOG2(EJavaRuntime);
-
- JavaVM* jvm; // Denotes a Java VM.
- JNIEnv* env; // Pointer to native method interface.
- JavaVMInitArgs vmArgs; // VM initialization arguments.
- JavaVMOption vmOption;
- vmOption.extraInfo = 0;
-
- LOG(EJavaRuntime, EInfo, "VM args:");
- JvmOptionArgs_t jvmOptions;
- for (int i = 0; i < mArgCount; i++)
- {
- vmOption.optionString = mArgs[i];
- jvmOptions.push_back(vmOption);
- LOG1(EJavaRuntime, EInfo, " %s",mArgs[i]); // codescanner::accessArrayElementWithoutCheck2
- }
- vmArgs.version = JNI_VERSION_1_4;
-
- // Initializing JavaVMInitArgs.
- // Contiguity for std::vector<T> is mandated by the standard as long
- // as T is not bool. [See 23.2.4./1].
- vmArgs.options = &((jvmOptions)[0]); // codescanner::accessArrayElementWithoutCheck2
- vmArgs.nOptions = jvmOptions.size();
- vmArgs.ignoreUnrecognized = JNI_FALSE;
-
- JavaOsLayer::startUpTrace("Starting VM()", -1, -1);
-
- // Creating the JVM.
- int res = JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &vmArgs);
- LOG1(EJavaRuntime, EInfo, "JNI_CreateJavaVM() returned. st = %d", res);
- if (res == 0)
- {
- // Converting the '.' to '/' in the main class
- // (com.nokia.Foo -> com/nokia/Foo)
- std::wstring& appMain = mAppAndArgs.front();
- std::replace(appMain.begin(), appMain.end(), '.', '/');
-
- // Convert the main class to UTF-8.
- ScopedCharPointer main(JavaCommonUtils::wstringToUtf8(appMain));
-
- // Find the main class.
- jclass mainClass = env->FindClass(main.get());
- LOG2(EJavaRuntime, EInfo, " mainClass (%s): %p", main.get(), mainClass);
- if (mainClass != 0)
- {
- // Find method static void main(String[] args) from the main class.
- jmethodID mainMethod = env->GetStaticMethodID(mainClass, "main",
- "([Ljava/lang/String;)V");
- LOG1(EJavaRuntime, EInfo, " mainMethod: %p", mainMethod);
- if (mainMethod != 0)
- {
- // Call the method static void main().
- env->CallStaticVoidMethod(mainClass, mainMethod,
- getApplicationArguments(env));
- LOG(EJavaRuntime, EInfo, " CallStaticVoidMethod returned");
- }
- else
- {
- std::string errorStr("Not able to find main() method.");
- throw RuntimeException(errorStr,
- __FILE__, __FUNCTION__, __LINE__);
- }
- }
- else
- {
- std::string errorStr("Main class was not found.");
- throw RuntimeException(errorStr, __FILE__, __FUNCTION__, __LINE__);
- }
- jvm->DestroyJavaVM();
- }
- else
- {
- std::string errorStr("JNI_CreateJavaVM failed. Reason = .");
- errorStr += JavaCommonUtils::intToString(res);
- throw RuntimeException(errorStr, __FILE__, __FUNCTION__, __LINE__);
- }
- return res;
-}
-
-
-void JvmStarterJni::completeArgumentContainers()
-{
- JELOG2(EJavaRuntime);
-
- // Set the used porting layer.
- mJvmArgs.push_back(L"-Dcom.nokia.jvm.port=sun.JvmPortJ2se");
-
- // Disable JIT, if requested.
- if (mJitDisabled)
- {
- mJvmArgs.push_back(L"-Xint");
- }
-
- // Add the classpath.
- if (mClassPath.length() > 0)
- {
- mClassPath.insert(0, L"-Djava.class.path=");
- mJvmArgs.push_front(mClassPath);
- LOG1(EJavaRuntime, EInfo, " mClassPath = %S", mClassPath.c_str());
- }
-
- // Add the extension classpath.
- if (mExtensionPath.length() > 0)
- {
- mExtensionPath.insert(0, L"-Djava.ext.dirs=");
- mJvmArgs.push_front(mExtensionPath);
- LOG1(EJavaRuntime, EInfo, " mExtensionPath = %S",
- mExtensionPath.c_str());
- }
-
- // Add the prepending boot classpath if set.
- if (mBootClassPathPrepend.length() > 0)
- {
- std::wstring bcpp(L"-Xbootclasspath/p:");
- bcpp += mBootClassPathPrepend;
- mJvmArgs.push_front(bcpp);
- LOG1(EJavaRuntime, EInfo, " bcpp = %S", bcpp.c_str());
- }
-
- // Add the appending boot classpath if set.
- if (mBootClassPathAppend.length() > 0)
- {
- std::wstring bcpa(L"-Xbootclasspath/a:");
- bcpa += mBootClassPathAppend;
- mJvmArgs.push_front(bcpa);
- LOG1(EJavaRuntime, EInfo, " bcpa = %S", bcpa.c_str());
- }
-
- std::wstring javaBinRoot;
- std::string binRoot;
- JavaOsLayer::getBinRoot(binRoot, false);
- javaBinRoot.assign(binRoot.begin(), binRoot.end());
-
- // Setting the java.library.path.
- std::wstring jlp(L"-Djava.library.path=");
- jlp += javaBinRoot;
- jlp += L"lib";
- mJvmArgs.push_front(jlp);
- LOG1(EJavaRuntime, EInfo, " jlp = %S", jlp.c_str());
-
- // Setting the java.home.
- std::wstring jh = L"-Djava.home=";
- const char* javaHome = getenv("JAVA_VM_HOME");
- if (javaHome == 0)
- {
- throw RuntimeException("JAVA_VM_HOME not defined",
- __FILE__, __FUNCTION__, __LINE__);
- }
- std::string jhs(javaHome);
- jh.append(jhs.begin(), jhs.end());
- mJvmArgs.push_front(jh);
- LOG1(EJavaRuntime, EInfo, " jh = %S", jh.c_str());
-
- // Define emma.properties to point to emma.properties file
- // which is used when Java code coverage is measured.
- std::wstring emma(L"-Demma.properties=");
- emma += javaBinRoot;
- emma += L"emma.properties";
- mJvmArgs.push_front(emma);
- LOG1(EJavaRuntime, EInfo, " emma = %S", emma.c_str());
-
- // Add the main class.
- mAppAndArgs.push_front(mMainClass);
- LOG1(EJavaRuntime, EInfo, " mMainClass = %S", mMainClass.c_str());
-}
-
-jobjectArray JvmStarterJni::getApplicationArguments(JNIEnv* env)
-{
- JELOG2(EJavaRuntime);
- // When using JNI_CreateJavaVM to start the JVM the arguments for the
- // Java application must be handled so that a jobjectArray is created
- // to contain Java Strings created using jni APIs.
-
- if (env == 0)
- {
- throw RuntimeException("JNIEnv was null",
- __FILE__, __FUNCTION__, __LINE__);
- }
-
- // Create the jobjectArray. mAppAndArgs container contains the main
- // class which must be taken into account.
- jobjectArray array =
- (jobjectArray)env->NewObjectArray(mAppAndArgs.size() - 1,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
- LOG(EJavaRuntime, EInfo, " Application arguments:");
- if (array != 0)
- {
- JvmArgs_t::iterator appAndArgsIter = mAppAndArgs.begin();
- // Skip the main class.
- ++appAndArgsIter;
-
- int i = 0;
-
- // Fill the object array with application arguments.
- for (; appAndArgsIter!= mAppAndArgs.end(); ++appAndArgsIter)
- {
- ScopedCharPointer appArg(JavaCommonUtils::wstringToUtf8(*appAndArgsIter));
- LOG1(EJavaRuntime, EInfo, " %s", appArg.get());
- env->SetObjectArrayElement(array, i++,
- env->NewStringUTF(appArg.get()));
- }
- }
- else
- {
- throw RuntimeException("jobjectArray was null",
- __FILE__, __FUNCTION__, __LINE__);
- }
- return array;
-}
-
-