Bom dia,
alguém sabe dizer como posso executar minha .class como arquivo executável do sistema operacional nativo, tal como o Eclipse no windows, por exemplo, que possui extensão .exe?
Bom dia,
alguém sabe dizer como posso executar minha .class como arquivo executável do sistema operacional nativo, tal como o Eclipse no windows, por exemplo, que possui extensão .exe?
poderia ser um .jar?
é o executável do java.
um .exe só com um programa devido, creio.
Oi,
Procure por exe4j, ele criar um exe de um .class
espero que tenha ajudado.
leossa e NataliaOliveira, bom dia!
é um .jar mesmo, como a Natalia disse.
Para gera-lo, no eclipse, como sitado pelo leossa, você clica com o botão direito sobre seu projeto e depois em EXPORT - JAVA - JAR FILE. A partir é auto-intuitivo você só vai selecionar o local onde deseja que seja gerado o arquivo.
Qualquer dúvida, sintam-se a vontade.
Abraços e bom dia.
Rapaz uma das coisas legais da linguagem de programação Java é o lance dela ser interpretada, e por esse motivo ela se torna independente de plataforma. Não vejo tantos motivos assim para se criar um executável para um programa Java, porém as exigências dos nossos clientes as vezes não possuem motivos aparentes. Uma alternativa muito interessante é utilizar um gerador de instaladores como o Install Shield for Java, tem uma versão triall pra baixar, ele gera um executável que imbute a JVM, cria ícones, desinstalador, etc. Caso você goste de programar em C, você pode criar um programa que utilize a dll que vem na JVM, chamada jvm.dll, para a partir de um programa C/C++ iniciar a JVM e executar uma classe Java.
Fiz um pequeno aplicativo em C para uma necessidade minha. Aí vai:
arquivo main.cpp
#include <jni.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <vector>
#include "DirectoryCrawler.hpp"
#define BUF_SIZE 512
#define CONFIG_FILE "mte.cfg"
using namespace std;
typedef jint (JNICALL *JavaVMProcPtr)(JavaVM **, void **, void*);
char javaHome[BUF_SIZE];
char projectHome[BUF_SIZE];
int setenv(const char *name, const char *value);
char *getenv(const char *name);
char* openDir();
void readConfig();
int main() {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[5];
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char* oldPath;
readConfig();
char jarsDir[BUF_SIZE];
char classesDir[BUF_SIZE];
strcpy(jarsDir, projectHome);
strcat(jarsDir, "lib\\");
strcpy(classesDir, projectHome);
strcat(classesDir, "classes\\");
//Reading the classpath
string classpath = "";
DirectoryCrawler crawler;
crawler.parseDirs(jarsDir);
vector<string>* jars = crawler.getFiles();
for (vector<string>::iterator i = jars->begin(); i != jars->end(); i++) {
string filename = *i;
classpath = classpath + ";" + filename;
}
options[0].optionString = "-Xms64M";
options[1].optionString = "-Xmx512M";
options[2].optionString = "-Xss512K";
options[3].optionString = "-Xoss400K";
options[4].optionString = "-Djava.class.path=.";
options[4].optionString = (char *)malloc(sizeof(char) * 5000000);
strcpy(options[4].optionString, "-Djava.class.path=.;tools.jar;");
strcat(options[4].optionString, projectHome);
strcat(options[4].optionString, ";");
strcat(options[4].optionString, classesDir);
strcat(options[4].optionString, classpath.c_str());
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = 5;
vm_args.ignoreUnrecognized = JNI_FALSE;
char pathValue[BUF_SIZE];
char dllPath[BUF_SIZE];
strcpy(pathValue, "%PATH%;");
strcat(pathValue, javaHome);
strcat(pathValue, "jre\\bin\\server");
strcpy(dllPath, javaHome);
strcat(dllPath, "jre\\bin\\server\\jvm.dll");
oldPath = getenv("PATH");
setenv("PATH", pathValue);
HMODULE hMoudle = LoadLibrary(dllPath);
JavaVMProcPtr javaVMPtr2 = (JavaVMProcPtr)(GetProcAddress(hMoudle, "JNI_CreateJavaVM"));
if(!javaVMPtr2) {
cerr << "Não foi possível obter um apontador para a função JNI_CreateJavaVM" << endl;
setenv("PATH", oldPath);
exit(1);
}
res = (*javaVMPtr2)(&jvm,(void**)&env,(void*)&vm_args);
if (res < 0) {
cerr << "Can't create Java VM" << endl;
setenv("PATH", oldPath);
exit(1);
}
cls = env->FindClass("project/MainClass");
if (cls == 0) {
cerr << "Can't find the Main class" << endl;
goto destroy;
}
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if (mid == 0) {
cerr<< "Can't find Prog.main" << endl;
goto destroy;
}
jstr = env->NewStringUTF(" from C++!");
if (jstr == 0) {
cerr << "Out of memory" << endl;
goto destroy;
}
args = env->NewObjectArray(1, env->FindClass("java/lang/String"), jstr);
if (args == 0) {
cerr << "Out of memory" << endl;
goto destroy;
}
env->CallStaticVoidMethod(cls, mid, args);
destroy:
setenv("PATH", oldPath);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jvm->DestroyJavaVM();
}
int setenv(const char *name, const char *value) {
LONG r;
size_t l;
HKEY k;
DWORD disp;
r = RegCreateKeyEx(HKEY_CURRENT_USER, "environment", 0, "class", 0, 0, NULL, &k, &disp);
r = RegSetValueEx(k, name, 0, REG_SZ, (BYTE*)value, (l + 1) * sizeof(char));
RegCloseKey(k);
if (r != ERROR_SUCCESS)
return -1;
return 0;
}
char *getenv(const char *name) {
static char buffer[BUF_SIZE];
static DWORD bufsize;
LONG r;
DWORD tp;
HKEY k;
r = RegOpenKeyEx(HKEY_CURRENT_USER, "environment", 0, 0, &k);
if (r != ERROR_SUCCESS)
return NULL;
bufsize = BUF_SIZE;
r = RegQueryValueEx(k, name, NULL, &tp, (LPBYTE)&buffer[0], &bufsize);
RegCloseKey(k);
if (r != ERROR_SUCCESS)
return NULL;
switch (tp) {
case REG_SZ:
return &buffer[0];
case REG_NONE:
case REG_BINARY:
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
case REG_EXPAND_SZ:
case REG_LINK:
case REG_MULTI_SZ:
case REG_RESOURCE_LIST:
default:
return NULL;
}
return NULL;
}
void readConfig() {
//Reading the configuration
ifstream config(CONFIG_FILE);
if (config.fail()) {
config.close();
MessageBox(NULL, "Não foi encontrado o arquivo de configuração.\nVocê deverá especificar o diretório de instalação do Java em seu computador.", "Configuração", MB_OK | MB_ICONWARNING | MB_TASKMODAL);
char* filename = openDir();
if (filename) {
strcpy(javaHome, filename);
MessageBox(NULL, "Agora você terá que indicar o diretório onde\no sistema está instalado.", "Diretório do eCompras", MB_OK | MB_ICONWARNING | MB_TASKMODAL);
filename = openDir();
if (filename) {
strcpy(projectHome, filename);
FILE *file = fopen(CONFIG_FILE, "w");
fprintf(file, "%s\n", javaHome);
fprintf(file, "%s", projectHome);
fclose(file);
return;
} else {
MessageBox(NULL, "Não foi possível configurar a sua aplicação.", "Erro", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(1);
return;
}
} else {
MessageBox(NULL, "Não foi possível configurar a sua aplicação.", "Erro", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(1);
return;
}
}
//The firs line of the file must contain the JAVA_HOME directory
config.getline(javaHome, BUF_SIZE);
//The second line of the file must contain the ECOMPRAS_HOME directory
config.getline(projectHome, BUF_SIZE);
//Closing the file
config.close();
}
char* openDir() {
OPENFILENAME ofn;
char szFile[BUF_SIZE];
HWND hwnd;
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
//
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
//
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Diretórios\0*.\0";
ofn.nFilterIndex = 0;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST;
strcat(ofn.lpstrFile, "Diretório Corrente");
// Display the Open dialog box.
if (GetOpenFileName(&ofn) == TRUE) {
static char filename[BUF_SIZE];
unsigned int i = 0;
for (; i < strlen(ofn.lpstrFile) - 18; i++) {
filename[i] = ofn.lpstrFile[i];
}
filename[i] = '\0';
return filename;
}
return NULL;
}
Arquivo DirectoryCrawler.hpp:
#ifndef DIRECTORYCRAWLER_HPP_INCLUDED
#define DIRECTORYCRAWLER_HPP_INCLUDED
#include <vector>
#include <string>
class DirectoryCrawler {
protected:
std::vector<std::string>* files;
public:
DirectoryCrawler();
~DirectoryCrawler();
void parseDirs(TCHAR *szPath);
std::vector<std::string>* getFiles() {
return files;
}
};
#endif // DIRECTORYCRAWLER_HPP_INCLUDED
Arquivo DirectoryCrawler.cpp:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "DirectoryCrawler.hpp"
using namespace std;
DirectoryCrawler::DirectoryCrawler() {
files = new vector<string>();
}
DirectoryCrawler::~DirectoryCrawler() {
delete files;
}
void DirectoryCrawler::parseDirs(TCHAR *szPath) {
TCHAR szCurDirPath[MAX_PATH + 1];
TCHAR szNewDirPath[MAX_PATH + 1];
WIN32_FIND_DATA data;
HANDLE hFind;
BOOL bContinue = TRUE;
sprintf(szCurDirPath, "%s*.*", szPath);
hFind = FindFirstFile(szCurDirPath, &data);
if (INVALID_HANDLE_VALUE == hFind) {
MessageBox(NULL, "Invalid handle! Aborting", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(0);
}
while (hFind && bContinue) {
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!(strcmp(data.cFileName, ".") == 0) && !(strcmp(data.cFileName, "..") == 0)) {
sprintf(szNewDirPath, "%s%s\\", szPath, data.cFileName);
parseDirs(szNewDirPath);
}
} else {
sprintf(szNewDirPath, "%s%s", szPath, data.cFileName);
files->push_back(string(szNewDirPath));
}
bContinue = FindNextFile(hFind, &data);
}
FindClose(hFind);
}
Esse aplicativo aê que eu terminei fazendo tenta localizar num arquivo de configuração os locais de instalação do projeto Java e da JVM. Caso não encontre ele abre duas janelas de diálogo por onde você indicará o caminho das mesmas.
O classpath da aplicação é configurado dinamicamente através dos diretórios bin e lib dentro do diretório da aplicação. E, por fim, será executada a classe project.Main.
Olá pessoal,
na verdade o que eu queria saber é como transformar meu .class em arquivo executável nativo do próprio sistema operacional, como o dlrodrigues falou. Sobre o Eclipse, eu quis dizer que ele se apresenta como um arquivo .exe no windows, e que eu saiba, o Eclipse é feito em Java. Me corrijam se eu estiver enganado.
O Eclipse, Oracle, Azureus e mais um monte de programas que utilizamos no dia-a-dia e são feitos em Java e que exportam para os usuários uma interface nativa executável foram feitos das formas que eu te falei. Ou foi criado utilizando um gerador de instaladores ou foi criado utilizando um aplicativo ad-hoc feito em C/C++ (como o exemplo de código que eu postei).
Porém, há compiladores de Java para código nativo, como por exemplo o GCJ. Porém eu não recomendo, eles estão sempre muuuuuito atrás das versões correntes do SDK da Sun, além de não serem tão compatíveis assim.
[quote=brunogamacatao]Rapaz uma das coisas legais da linguagem de programação Java é o lance dela ser interpretada, e por esse motivo ela se torna independente de plataforma. Não vejo tantos motivos assim para se criar um executável para um programa Java, porém as exigências dos nossos clientes as vezes não possuem motivos aparentes. Uma alternativa muito interessante é utilizar um gerador de instaladores como o Install Shield for Java, tem uma versão triall pra baixar, ele gera um executável que imbute a JVM, cria ícones, desinstalador, etc. Caso você goste de programar em C, você pode criar um programa que utilize a dll que vem na JVM, chamada jvm.dll, para a partir de um programa C/C++ iniciar a JVM e executar uma classe Java.
Fiz um pequeno aplicativo em C para uma necessidade minha. Aí vai:
arquivo main.cpp
#include <jni.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <vector>
#include "DirectoryCrawler.hpp"
#define BUF_SIZE 512
#define CONFIG_FILE "mte.cfg"
using namespace std;
typedef jint (JNICALL *JavaVMProcPtr)(JavaVM **, void **, void*);
char javaHome[BUF_SIZE];
char projectHome[BUF_SIZE];
int setenv(const char *name, const char *value);
char *getenv(const char *name);
char* openDir();
void readConfig();
int main() {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[5];
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char* oldPath;
readConfig();
char jarsDir[BUF_SIZE];
char classesDir[BUF_SIZE];
strcpy(jarsDir, projectHome);
strcat(jarsDir, "lib\\");
strcpy(classesDir, projectHome);
strcat(classesDir, "classes\\");
//Reading the classpath
string classpath = "";
DirectoryCrawler crawler;
crawler.parseDirs(jarsDir);
vector<string>* jars = crawler.getFiles();
for (vector<string>::iterator i = jars->begin(); i != jars->end(); i++) {
string filename = *i;
classpath = classpath + ";" + filename;
}
options[0].optionString = "-Xms64M";
options[1].optionString = "-Xmx512M";
options[2].optionString = "-Xss512K";
options[3].optionString = "-Xoss400K";
options[4].optionString = "-Djava.class.path=.";
options[4].optionString = (char *)malloc(sizeof(char) * 5000000);
strcpy(options[4].optionString, "-Djava.class.path=.;tools.jar;");
strcat(options[4].optionString, projectHome);
strcat(options[4].optionString, ";");
strcat(options[4].optionString, classesDir);
strcat(options[4].optionString, classpath.c_str());
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = 5;
vm_args.ignoreUnrecognized = JNI_FALSE;
char pathValue[BUF_SIZE];
char dllPath[BUF_SIZE];
strcpy(pathValue, "%PATH%;");
strcat(pathValue, javaHome);
strcat(pathValue, "jre\\bin\\server");
strcpy(dllPath, javaHome);
strcat(dllPath, "jre\\bin\\server\\jvm.dll");
oldPath = getenv("PATH");
setenv("PATH", pathValue);
HMODULE hMoudle = LoadLibrary(dllPath);
JavaVMProcPtr javaVMPtr2 = (JavaVMProcPtr)(GetProcAddress(hMoudle, "JNI_CreateJavaVM"));
if(!javaVMPtr2) {
cerr << "Não foi possível obter um apontador para a função JNI_CreateJavaVM" << endl;
setenv("PATH", oldPath);
exit(1);
}
res = (*javaVMPtr2)(&jvm,(void**)&env,(void*)&vm_args);
if (res < 0) {
cerr << "Can't create Java VM" << endl;
setenv("PATH", oldPath);
exit(1);
}
cls = env->FindClass("project/MainClass");
if (cls == 0) {
cerr << "Can't find the Main class" << endl;
goto destroy;
}
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if (mid == 0) {
cerr<< "Can't find Prog.main" << endl;
goto destroy;
}
jstr = env->NewStringUTF(" from C++!");
if (jstr == 0) {
cerr << "Out of memory" << endl;
goto destroy;
}
args = env->NewObjectArray(1, env->FindClass("java/lang/String"), jstr);
if (args == 0) {
cerr << "Out of memory" << endl;
goto destroy;
}
env->CallStaticVoidMethod(cls, mid, args);
destroy:
setenv("PATH", oldPath);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jvm->DestroyJavaVM();
}
int setenv(const char *name, const char *value) {
LONG r;
size_t l;
HKEY k;
DWORD disp;
r = RegCreateKeyEx(HKEY_CURRENT_USER, "environment", 0, "class", 0, 0, NULL, &k, &disp);
r = RegSetValueEx(k, name, 0, REG_SZ, (BYTE*)value, (l + 1) * sizeof(char));
RegCloseKey(k);
if (r != ERROR_SUCCESS)
return -1;
return 0;
}
char *getenv(const char *name) {
static char buffer[BUF_SIZE];
static DWORD bufsize;
LONG r;
DWORD tp;
HKEY k;
r = RegOpenKeyEx(HKEY_CURRENT_USER, "environment", 0, 0, &k);
if (r != ERROR_SUCCESS)
return NULL;
bufsize = BUF_SIZE;
r = RegQueryValueEx(k, name, NULL, &tp, (LPBYTE)&buffer[0], &bufsize);
RegCloseKey(k);
if (r != ERROR_SUCCESS)
return NULL;
switch (tp) {
case REG_SZ:
return &buffer[0];
case REG_NONE:
case REG_BINARY:
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
case REG_EXPAND_SZ:
case REG_LINK:
case REG_MULTI_SZ:
case REG_RESOURCE_LIST:
default:
return NULL;
}
return NULL;
}
void readConfig() {
//Reading the configuration
ifstream config(CONFIG_FILE);
if (config.fail()) {
config.close();
MessageBox(NULL, "Não foi encontrado o arquivo de configuração.\nVocê deverá especificar o diretório de instalação do Java em seu computador.", "Configuração", MB_OK | MB_ICONWARNING | MB_TASKMODAL);
char* filename = openDir();
if (filename) {
strcpy(javaHome, filename);
MessageBox(NULL, "Agora você terá que indicar o diretório onde\no sistema está instalado.", "Diretório do eCompras", MB_OK | MB_ICONWARNING | MB_TASKMODAL);
filename = openDir();
if (filename) {
strcpy(projectHome, filename);
FILE *file = fopen(CONFIG_FILE, "w");
fprintf(file, "%s\n", javaHome);
fprintf(file, "%s", projectHome);
fclose(file);
return;
} else {
MessageBox(NULL, "Não foi possível configurar a sua aplicação.", "Erro", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(1);
return;
}
} else {
MessageBox(NULL, "Não foi possível configurar a sua aplicação.", "Erro", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(1);
return;
}
}
//The firs line of the file must contain the JAVA_HOME directory
config.getline(javaHome, BUF_SIZE);
//The second line of the file must contain the ECOMPRAS_HOME directory
config.getline(projectHome, BUF_SIZE);
//Closing the file
config.close();
}
char* openDir() {
OPENFILENAME ofn;
char szFile[BUF_SIZE];
HWND hwnd;
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
//
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
//
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Diretórios\0*.\0";
ofn.nFilterIndex = 0;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST;
strcat(ofn.lpstrFile, "Diretório Corrente");
// Display the Open dialog box.
if (GetOpenFileName(&ofn) == TRUE) {
static char filename[BUF_SIZE];
unsigned int i = 0;
for (; i < strlen(ofn.lpstrFile) - 18; i++) {
filename[i] = ofn.lpstrFile[i];
}
filename[i] = '\0';
return filename;
}
return NULL;
}
Arquivo DirectoryCrawler.hpp:
#ifndef DIRECTORYCRAWLER_HPP_INCLUDED
#define DIRECTORYCRAWLER_HPP_INCLUDED
#include <vector>
#include <string>
class DirectoryCrawler {
protected:
std::vector<std::string>* files;
public:
DirectoryCrawler();
~DirectoryCrawler();
void parseDirs(TCHAR *szPath);
std::vector<std::string>* getFiles() {
return files;
}
};
#endif // DIRECTORYCRAWLER_HPP_INCLUDED
Arquivo DirectoryCrawler.cpp:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "DirectoryCrawler.hpp"
using namespace std;
DirectoryCrawler::DirectoryCrawler() {
files = new vector<string>();
}
DirectoryCrawler::~DirectoryCrawler() {
delete files;
}
void DirectoryCrawler::parseDirs(TCHAR *szPath) {
TCHAR szCurDirPath[MAX_PATH + 1];
TCHAR szNewDirPath[MAX_PATH + 1];
WIN32_FIND_DATA data;
HANDLE hFind;
BOOL bContinue = TRUE;
sprintf(szCurDirPath, "%s*.*", szPath);
hFind = FindFirstFile(szCurDirPath, &data);
if (INVALID_HANDLE_VALUE == hFind) {
MessageBox(NULL, "Invalid handle! Aborting", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
exit(0);
}
while (hFind && bContinue) {
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!(strcmp(data.cFileName, ".") == 0) && !(strcmp(data.cFileName, "..") == 0)) {
sprintf(szNewDirPath, "%s%s\\", szPath, data.cFileName);
parseDirs(szNewDirPath);
}
} else {
sprintf(szNewDirPath, "%s%s", szPath, data.cFileName);
files->push_back(string(szNewDirPath));
}
bContinue = FindNextFile(hFind, &data);
}
FindClose(hFind);
}
Esse aplicativo aê que eu terminei fazendo tenta localizar num arquivo de configuração os locais de instalação do projeto Java e da JVM. Caso não encontre ele abre duas janelas de diálogo por onde você indicará o caminho das mesmas.
O classpath da aplicação é configurado dinamicamente através dos diretórios bin e lib dentro do diretório da aplicação. E, por fim, será executada a classe project.Main.[/quote]
brunogamacatao, concordo com você, mas esta “necessidade” dos clientes é o ponto pelo qual eu me interessei em perguntar.
Interessante sua idéia, e seu código. Já gostei muito de programar em C, mas estou bastante enferrujado.
Quanto ao InstallShield for Java que você mencionou, não sei se é exatamente a idéia por trás do eclipse, mas de uma forma ou de outra, é algo desse tipo que estou procurando.