Skip to content

Commit

Permalink
Initial commit of new launcher
Browse files Browse the repository at this point in the history
Change-Id: Ib6e2b400161fb1624b874037e6100c04259c1816
Reviewed-on: http://gerrit.dmdirc.com/3238
Automatic-Compile: DMDirc Build Manager
Reviewed-by: Chris Smith <[email protected]>
  • Loading branch information
Greg Holmes authored and csmith committed Feb 26, 2014
1 parent eeacaf4 commit bd4dc5e
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
/output/
/windows/files/
new-windows-launcher/build/*
new-windows-launcher/dist/*
new-windows-launcher/nbproject/Makefile-Debug.mk
new-windows-launcher/nbproject/Makefile-Release.mk
new-windows-launcher/nbproject/Makefile-variables.mk
new-windows-launcher/nbproject/Package-Debug.bash
new-windows-launcher/nbproject/Package-Release.bash
new-windows-launcher/nbproject/private/*
new-windows-launcher/nbproject/configurations.xml
new-windows-launcher/jvm.a
5 changes: 5 additions & 0 deletions new-windows-launcher/.dep.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
80 changes: 80 additions & 0 deletions new-windows-launcher/JVMLauncher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "JVMLauncher.h"

JVMLauncher::JVMLauncher(std::string path) {
//Get JVM.dll via JAVA_HOME
javaHome = getenv("JAVA_HOME");
if (javaHome.empty()) {
throw JVMLauncherException("JAVA_HOME not defined");
}
jvmDll = javaHome + "\\jre\\bin\\server\\jvm.dll";
//Do something better here..
appHome.append(path);
jars.push_back("DMDirc.jar");
}

void JVMLauncher::LaunchJVM() {
//Build library path
std::string strJavaLibraryPath = "-Djava.library.path=";
strJavaLibraryPath += javaHome + "\\lib" + "," + javaHome + "\\jre\\lib";
//Add jars to classpath
std::string strJavaClassPath = "-Djava.class.path=";
for (int i = 0; i < jars.size() - 1; i++) {
strJavaClassPath += appHome + jars[i] + ";";
}
strJavaClassPath += appHome + jars[jars.size() - 1];
//Configure JVM Options
JavaVMOption options[2];
options[0].optionString = const_cast<char*> (strJavaClassPath.c_str());
options[1].optionString = const_cast<char*> (strJavaLibraryPath.c_str());
//Configure VM args
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6; //JNI Version 1.4 and above
vm_args.options = options;
vm_args.nOptions = 3;
vm_args.ignoreUnrecognized = JNI_FALSE;
//Load JVM.dll
jvmDllInstance = LoadLibraryA(jvmDll.c_str());
if (jvmDllInstance == 0) {
throw JVMLauncherException("Cannot load jvm.dll");
}
//Load JVM
jvmInstance = (CreateJavaVM) GetProcAddress(jvmDllInstance, "JNI_CreateJavaVM");
if (jvmInstance == NULL) {
throw JVMLauncherException("Cannot load jvm.dll");
}
//Create the JVM
jint res = jvmInstance(&jvm, (void **) &jvmEnv, &vm_args);
if (res < 0) {
throw JVMLauncherException("Could not launch the JVM");
}
//Get main class
mainClass = jvmEnv->FindClass("com/dmdirc/Main");
checkForException();
//Get main method
mainMethod = jvmEnv->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
checkForException();
//Attach to main thread
jvm->AttachCurrentThread((LPVOID*) &jvmEnv, NULL);
//Get main method args
jclass StringClass = jvmEnv->FindClass("java/lang/String");
jobjectArray jargs = jvmEnv->NewObjectArray(0, StringClass, NULL);
//Call main method
jvmEnv->CallStaticVoidMethod(mainClass, mainMethod, jargs);
jvm->DestroyJavaVM();
checkForException();
}

void JVMLauncher::checkForException() {
//Check exception happened
jthrowable ex = jvmEnv->ExceptionOccurred();
if (ex != NULL) {
//clear exception
jvmEnv->ExceptionClear();
//Grab info about exception and throw
jmethodID toString = jvmEnv->GetMethodID(jvmEnv->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
jstring estring = (jstring) jvmEnv->CallObjectMethod(ex, toString);
jboolean isCopy;
std::string message = jvmEnv->GetStringUTFChars(estring, &isCopy);
throw JVMLauncherException(message);
}
}
36 changes: 36 additions & 0 deletions new-windows-launcher/JVMLauncher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef JVMLAUNCHER_H
#define JVMLAUNCHER_H

#include <stdexcept>
#include <windows.h>
#include <tchar.h>
#include <jni.h>
#include <string>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <ostream>
#include "JVMLauncherException.cpp"

class JVMLauncher {
public:
JVMLauncher(std::string);
void LaunchJVM();
private:
typedef jint(JNICALL *CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
HINSTANCE jvmDllInstance;
std::string javaHome;
std::string appHome;
std::string jvmDll;
std::vector<std::string> jars;
CreateJavaVM jvmInstance;
jclass mainClass;
jmethodID mainMethod;
JNIEnv *jvmEnv;
JavaVM *jvm;
void checkForException();
protected:
};

#endif /* JVMLAUNCHER_H */

10 changes: 10 additions & 0 deletions new-windows-launcher/JVMLauncherException.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;

class JVMLauncherException: public runtime_error {
public:
JVMLauncherException(const string& message) : runtime_error(message) {
};
};
128 changes: 128 additions & 0 deletions new-windows-launcher/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL


# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin


# build
build: .build-post

.build-pre:
# Add your pre 'build' code here...

.build-post: .build-impl
# Add your post 'build' code here...


# clean
clean: .clean-post

.clean-pre:
# Add your pre 'clean' code here...

.clean-post: .clean-impl
# Add your post 'clean' code here...


# clobber
clobber: .clobber-post

.clobber-pre:
# Add your pre 'clobber' code here...

.clobber-post: .clobber-impl
# Add your post 'clobber' code here...


# all
all: .all-post

.all-pre:
# Add your pre 'all' code here...

.all-post: .all-impl
# Add your post 'all' code here...


# build tests
build-tests: .build-tests-post

.build-tests-pre:
# Add your pre 'build-tests' code here...

.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...


# run tests
test: .test-post

.test-pre: build-tests
# Add your pre 'test' code here...

.test-post: .test-impl
# Add your post 'test' code here...


# help
help: .help-post

.help-pre:
# Add your pre 'help' code here...

.help-post: .help-impl
# Add your post 'help' code here...



# include project implementation makefile
include nbproject/Makefile-impl.mk

# include project make variables
include nbproject/Makefile-variables.mk
9 changes: 9 additions & 0 deletions new-windows-launcher/Updater.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "Updater.h"

void Updater::MoveRunningExecutable() {
TCHAR buffer[MAX_PATH] = {0};
DWORD bufSize = sizeof (buffer) / sizeof (*buffer);
GetModuleFileName(NULL, buffer, bufSize);
MoveFile(buffer, "old.exe");
CopyFile("old.exe", buffer, TRUE);
}
16 changes: 16 additions & 0 deletions new-windows-launcher/Updater.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef UPDATER_H
#define UPDATER_H

#include <cstdlib>
#include <windows.h>

class Updater {
public:
Updater();
private:
void MoveRunningExecutable();

};

#endif /* UPDATER_H */

17 changes: 17 additions & 0 deletions new-windows-launcher/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <cstdlib>
#include <iostream>

#include "JVMLauncher.h"

int main(int argc, char** argv) {
JVMLauncher* jvmlauncher = new JVMLauncher("C:\\");
try {
jvmlauncher->LaunchJVM();
} catch (JVMLauncherException& ex) {
std::cout << "Launching the JVM failed" << std::endl;
std::cout << ex.what() << std::endl;
std::cout << "Press any key to exit" << std::endl;
std::cin.ignore(1);
}
return EXIT_SUCCESS;
}
Loading

0 comments on commit bd4dc5e

Please sign in to comment.