Hi, I have a pretty basic vc++/vs question, but the googles are failing me. I've seen this question posed before, but none of the proposed solutions work for me. I come from a very high-level language background (java/c#), so these pesky linking issues are alien to me. I appreciate your patience...
My problem is that when I send my exe to other folks, they cannot run the exe.
It works fine on my machine, presumably because I have all the vc++/vs build tools and libs. I think that I understand what's going on, but I don't know how to fix it.
The app is a java webapp, that runs under jetty, that I would like to distribute as a completely standalone windows exe and nt service. As simply as possible.
I have one c++ class that I wrote that loads the jvm and calls into the main()
of my my java app.
I'm quite sure I just need to tweak something in my sln/vcproj file, but I'm not sure what.
I'm building via ant (yes, it is indeed strange to see msbuild output from an ant build... :)
tia, -neil
"C++ Command Line":
/O2 /Oi /GL /D "_MBCS" /FD /EHsc /MT /Gy /Fo"Release\\" /Fd"Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
"Linker Command Line":
/OUT:"<myExe>" /NOLOGO /MANIFEST /MANIFESTFILE:"Release\<myExe>.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"c:\<myPdb>" /OPT:REF /OPT:ICF /LTCG /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
"Manifest Command Line":
/nologo /outputresource:"<myExe>;#1"
Code:
#include <iostream>
#include <string>
#include <tchar.h>
#include <windows.h>
#include <winbase.h>
#include "include/jni.h"
using namespace std;
#define CLASS_NAME "<my class that has a main()>"
#define CLASS_PATH "-Djava.class.path=<all of my jars>"
typedef jint (JNICALL *CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
CreateJavaVM createJVM;
class Runner {
public:
int Run() {
JavaVM *vm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint res;
JNIEnv *env;
jclass cls;
jmethodID mid;
options[0].optionString = CLASS_PATH;
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_FALSE;
HINSTANCE handle = GetJvmLibrary();
if( handle == 0) {
printf("Failed to load the jvm.");
return -1;
}
createJVM = (CreateJavaVM)GetProcAddress(handle, "JNI_CreateJavaVM");
res = createJVM(&vm, (void **)&env, &vm_args);
if (res < 0) {
printf("JVM could not be loaded.");
return -1;
}
cls = env->FindClass(CLASS_NAME);
if(cls == 0) {
printf("Exception in thread \"main\" java.lang.NoClassDefFoundError: %s\n", CLASS_NAME);
return -1;
}
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if(mid == 0) {
printf("Exception in thread \"main\" java.lang.NoSuchMethodError: main\n");
return -1;
}
env->CallStaticVoidMethod(cls, mid, "");
if(env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
return 0;
}
private:
static HINSTANCE GetJvmLibrary()
{
char lszVersionValue[8192];
char lszPathValue[8192];
HKEY hKey;
LONG returnStatus;
DWORD dwType=REG_SZ;
DWORD dwSize=8192;
returnStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\JavaSoft\\Java Runtime Environment",
NULL,
KEY_ALL_ACCESS,
&hKey);
if (returnStatus == ERROR_SUCCESS)
{
returnStatus = RegQueryValueEx(
hKey,
TEXT("CurrentVersion"),
NULL,
&dwType,
(LPBYTE)&lszVersionValue,
&dwSize);
if (returnStatus == ERROR_SUCCESS)
{
// error. need to figure out what TODO here.
}
}
char buff[8192];
memset(buff,0,sizeof(char)*8192);
sprintf(buff, "SOFTWARE\\JavaSoft\\Java Runtime Environment\\%s", lszVersionValue);
printf(buff);
returnStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
buff,
NULL,
KEY_ALL_ACCESS,
&hKey);
if (returnStatus == ERROR_SUCCESS)
{
returnStatus = RegQueryValueEx(
hKey,
TEXT("RunTimeLib"),
NULL,
&dwType,
(LPBYTE)&lszPathValue,
&dwSize);
while (returnStatus == ERROR_MORE_DATA)
{
returnStatus = RegQueryValueEx(
hKey,
TEXT("RunTimeLib"),
NULL,
&dwType,
(LPBYTE)&lszPathValue,
&(dwSize+=4096));
}
if (returnStatus != ERROR_SUCCESS)
{
printf("failed to read the path to the jvm dll because of: %d",returnStatus);
}
}
RegCloseKey(hKey);
HINSTANCE handle = LoadLibrary(lszPathValue);
if( handle == 0) {
printf("Failed to LoadLibrary(jvm).\n");
} else {
printf("succussfully loaded the jvm.\n");
}
return handle;
}
};
int main()
{
return Runner().Run();
}