logic: handle java not found on windows and mac
* implemented java will not be used if it is not found on system * add jni libraries weak linked for Mac * use dlopen for lazy library loading * added java path to preferences
This commit is contained in:
+22
-5
@@ -212,7 +212,11 @@ target_include_directories(${LIB_PROJECT_NAME} SYSTEM
|
||||
"${CMAKE_SOURCE_DIR}/src/external"
|
||||
)
|
||||
|
||||
target_link_libraries(${LIB_PROJECT_NAME} ${Boost_LIBRARIES} ${LIB_LICENSE_PROJECT_NAME} ${JNI_LIBRARIES})
|
||||
if (WIN32)
|
||||
target_link_libraries(${LIB_PROJECT_NAME} ${Boost_LIBRARIES} ${LIB_LICENSE_PROJECT_NAME} ${JNI_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(${LIB_PROJECT_NAME} ${Boost_LIBRARIES} ${LIB_LICENSE_PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
# Lib Parser -------------------------------------------------------------------
|
||||
|
||||
@@ -394,11 +398,24 @@ create_source_groups(${APP_FILES})
|
||||
target_link_libraries(${APP_PROJECT_NAME} ${LIB_GUI_PROJECT_NAME} ${LIB_PARSER_PROJECT_NAME} ${LIB_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME})
|
||||
|
||||
if (WIN32)
|
||||
SET_TARGET_PROPERTIES(
|
||||
${APP_PROJECT_NAME} PROPERTIES
|
||||
LINK_FLAGS "/DELAYLOAD:jvm.dll")
|
||||
SET_TARGET_PROPERTIES(
|
||||
${APP_PROJECT_NAME} PROPERTIES
|
||||
LINK_FLAGS "/DELAYLOAD:jvm.dll"
|
||||
)
|
||||
elseif (APPLE)
|
||||
set(LAZY_LIB_FLAGS "")
|
||||
|
||||
foreach (_lib ${JNI_LIBRARIES})
|
||||
set (LAZY_LIB_FLAGS "${LAZY_LIB_FLAGS} -lazy_library ${_lib}")
|
||||
endforeach()
|
||||
|
||||
SET_TARGET_PROPERTIES(
|
||||
${APP_PROJECT_NAME} PROPERTIES
|
||||
LINK_FLAGS ${LAZY_LIB_FLAGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
set_property(
|
||||
TARGET ${APP_PROJECT_NAME}
|
||||
PROPERTY INCLUDE_DIRECTORIES
|
||||
@@ -601,7 +618,7 @@ target_link_libraries(${TEST_PROJECT_NAME} ${LIB_PARSER_PROJECT_NAME} ${LIB_PROJ
|
||||
|
||||
if (WIN32)
|
||||
SET_TARGET_PROPERTIES(
|
||||
${TEST_PROJECT_NAME} PROPERTIES
|
||||
${TEST_PROJECT_NAME} PROPERTIES
|
||||
LINK_FLAGS "/DELAYLOAD:jvm.dll")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public class JavaIndexer
|
||||
{
|
||||
public static void processFile(int address, String filePath, String fileContent, String classPath)
|
||||
{
|
||||
System.out.println("indexing file: " + filePath);
|
||||
// System.out.println("indexing file: " + filePath);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -33,8 +33,8 @@ public class JavaIndexer
|
||||
{
|
||||
try
|
||||
{
|
||||
JarTypeSolver jarTypeSolver = new JarTypeSolver(path);
|
||||
typeSolver.add(jarTypeSolver);
|
||||
JarTypeSolver solver = new JarTypeSolver(path);
|
||||
typeSolver.add(solver);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
#include "data/parser/java/TaskParseJava.h"
|
||||
#include "isTrial.h"
|
||||
|
||||
JavaProject::~JavaProject()
|
||||
{
|
||||
@@ -26,7 +27,7 @@ JavaProject::JavaProject(std::shared_ptr<JavaProjectSettings> projectSettings, S
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
if (!JavaEnvironmentFactory::getInstance())
|
||||
if (!JavaEnvironmentFactory::getInstance() && !isTrial())
|
||||
{
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
"data/java/asm-5.0.3.jar" + separator +
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
|
||||
void JavaEnvironmentFactory::createInstance(std::string classPath)
|
||||
{
|
||||
@@ -18,24 +26,63 @@ void JavaEnvironmentFactory::createInstance(std::string classPath)
|
||||
{
|
||||
LOG_ERROR("java classpath cannot be changed!");
|
||||
// todo: implement destroying the old factory instance and create a new one.
|
||||
// may be not so easy... there can only be one java env per process (which can never be destroyed) -.-
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s_classPath = classPath;
|
||||
bool javaFound = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
{ // todo: make this windows only
|
||||
std::string env1 = getenv("path");
|
||||
{
|
||||
std::string oldPathContent = getenv("path");
|
||||
|
||||
std::string javapath = ApplicationSettings::getInstance()->getJavaPath() + "/client/";
|
||||
putenv(("path=" + env1 + ";" + javapath).c_str()); // path env is only modified in the scope of this process.
|
||||
putenv(("path=" + oldPathContent + ";" + javapath).c_str()); // path env is only modified in the scope of this process.
|
||||
|
||||
javaFound = FileSystem::exists(javapath + "jvm.dll");
|
||||
}
|
||||
#endif
|
||||
using namespace std;
|
||||
|
||||
JavaVM* jvm; // Pointer to the JVM (Java Virtual Machine)
|
||||
JNIEnv* env; // Pointer to native interface
|
||||
#ifdef __APPLE__
|
||||
{
|
||||
std::string javapath = ApplicationSettings::getInstance()->getJavaPath();
|
||||
void* handle = nullptr;
|
||||
|
||||
if (javapath.size())
|
||||
{
|
||||
handle = dlopen((javapath + "/jre/lib/server/libjvm.dylib").c_str(), RTLD_NOW);
|
||||
}
|
||||
|
||||
if (!handle && javapath.size())
|
||||
{
|
||||
handle = dlopen((javapath + "/libjvm.dylib").c_str(), RTLD_NOW);
|
||||
}
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
handle = dlopen("libjvm.dylib", RTLD_NOW);
|
||||
}
|
||||
|
||||
if (handle)
|
||||
{
|
||||
javaFound = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!javaFound)
|
||||
{
|
||||
std::string errorMessage = "Unable to locate Java on this machine.";
|
||||
LOG_ERROR(errorMessage);
|
||||
MessageStatus(errorMessage, true, false).dispatch();
|
||||
return;
|
||||
}
|
||||
|
||||
s_classPath = classPath;
|
||||
|
||||
JavaVM* jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
|
||||
JNIEnv* env = nullptr; // Pointer to native interface
|
||||
|
||||
JavaVMInitArgs vm_args; // Initialization arguments
|
||||
JavaVMOption* options = new JavaVMOption[3]; // JVM invocation options
|
||||
@@ -44,38 +91,41 @@ void JavaEnvironmentFactory::createInstance(std::string classPath)
|
||||
options[1].optionString = const_cast<char*>("-Xms1m");
|
||||
std::string maximumMemoryOprionString = "-Xmx" + std::to_string(ApplicationSettings::getInstance()->getJavaMaximumMemory()) + "m";
|
||||
options[2].optionString = const_cast<char*>(maximumMemoryOprionString.c_str());
|
||||
// options[3].optionString = "-verbose:jni";
|
||||
vm_args.version = JNI_VERSION_1_6; // minimum Java version
|
||||
vm_args.nOptions = 3; // number of options
|
||||
vm_args.version = JNI_VERSION_1_6;
|
||||
vm_args.nOptions = 3;
|
||||
vm_args.options = options;
|
||||
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
|
||||
|
||||
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
|
||||
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
|
||||
|
||||
delete [] options;
|
||||
|
||||
if(rc != JNI_OK)
|
||||
{
|
||||
std::string errorMessage;
|
||||
if(rc == JNI_EVERSION)
|
||||
{
|
||||
LOG_ERROR("JVM is oudated and doesn't meet requirements");
|
||||
errorMessage = "JVM is oudated and doesn't meet requirements";
|
||||
}
|
||||
else if(rc == JNI_ENOMEM)
|
||||
{
|
||||
LOG_ERROR("not enough memory for JVM");
|
||||
errorMessage = "not enough memory for JVM";
|
||||
}
|
||||
else if(rc == JNI_EINVAL)
|
||||
{
|
||||
LOG_ERROR("invalid ragument for launching JVM");
|
||||
errorMessage = "invalid argument for launching JVM";
|
||||
}
|
||||
else if(rc == JNI_EEXIST)
|
||||
{
|
||||
LOG_ERROR("the process can only launch one JVM an not more");
|
||||
errorMessage = "the process can only launch one JVM an not more";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "could not create the JVM instance (error code " << rc << ")");
|
||||
errorMessage = "could not create the JVM instance (error code " + std::to_string(rc) + ")";
|
||||
}
|
||||
|
||||
LOG_ERROR(errorMessage);
|
||||
MessageStatus("Error while creating Java environment: " + errorMessage, true, false).dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -41,6 +41,11 @@ void QtLocationPicker::paintEvent(QPaintEvent*)
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
void QtLocationPicker::setPlaceholderText(QString text)
|
||||
{
|
||||
m_data->setPlaceholderText(text);
|
||||
}
|
||||
|
||||
QString QtLocationPicker::getText()
|
||||
{
|
||||
return m_data->text();
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
|
||||
virtual void paintEvent(QPaintEvent*) override;
|
||||
|
||||
void setPlaceholderText(QString text);
|
||||
QString getText();
|
||||
void setText(QString text);
|
||||
void clearText();
|
||||
|
||||
@@ -133,6 +133,32 @@ void QtProjectWizzardContentPreferences::populateForm(QGridLayout* layout, int&
|
||||
);
|
||||
|
||||
row++;
|
||||
|
||||
layout->setRowMinimumHeight(row++, 20);
|
||||
|
||||
// Java
|
||||
layout->addWidget(createFormTitle("JAVA"), row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignLeft);
|
||||
row++;
|
||||
|
||||
// java path
|
||||
m_javaPath = new QtLocationPicker(this);
|
||||
m_javaPath->setPickDirectory(true);
|
||||
m_javaPath->setPlaceholderText("<jdk_root>");
|
||||
|
||||
layout->addWidget(createFormLabel("Java Path"), row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignRight);
|
||||
layout->addWidget(m_javaPath, row, QtProjectWizzardWindow::BACK_COL);
|
||||
|
||||
addHelpButton(
|
||||
"Location of your java installation so that dynamic libraries of JVM can be found."
|
||||
, layout, row
|
||||
);
|
||||
row++;
|
||||
|
||||
layout->setRowMinimumHeight(row++, 20);
|
||||
|
||||
// C/C++
|
||||
layout->addWidget(createFormTitle("C/C++"), row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignLeft);
|
||||
row++;
|
||||
}
|
||||
|
||||
void QtProjectWizzardContentPreferences::load()
|
||||
@@ -159,6 +185,11 @@ void QtProjectWizzardContentPreferences::load()
|
||||
|
||||
m_threads->setCurrentIndex(appSettings->getIndexerThreadCount() - 1);
|
||||
m_fatalErrors->setChecked(appSettings->getShowExternalNonFatalErrors());
|
||||
|
||||
if (m_javaPath)
|
||||
{
|
||||
m_javaPath->setText(QString::fromStdString(appSettings->getJavaPath()));
|
||||
}
|
||||
}
|
||||
|
||||
void QtProjectWizzardContentPreferences::save()
|
||||
@@ -181,6 +212,11 @@ void QtProjectWizzardContentPreferences::save()
|
||||
|
||||
appSettings->setIndexerThreadCount(m_threads->currentIndex() + 1);
|
||||
appSettings->setShowExternalNonFatalErrors(m_fatalErrors->isChecked());
|
||||
|
||||
if (m_javaPath)
|
||||
{
|
||||
appSettings->setJavaPath(m_javaPath->getText().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
bool QtProjectWizzardContentPreferences::check()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "qt/element/QtLocationPicker.h"
|
||||
#include "qt/window/project_wizzard/QtProjectWizzardContent.h"
|
||||
|
||||
class QtProjectWizzardContentPreferences
|
||||
@@ -31,14 +32,16 @@ private:
|
||||
QLineEdit* m_fontFace;
|
||||
QComboBox* m_fontSize;
|
||||
QComboBox* m_tabWidth;
|
||||
|
||||
QComboBox* m_colorSchemes;
|
||||
QLineEdit* m_scrollSpeed;
|
||||
std::vector<FilePath> m_colorSchemePaths;
|
||||
int m_oldColorSchemeIndex;
|
||||
|
||||
QComboBox* m_threads;
|
||||
QCheckBox* m_fatalErrors;
|
||||
|
||||
std::vector<FilePath> m_colorSchemePaths;
|
||||
int m_oldColorSchemeIndex;
|
||||
QtLocationPicker* m_javaPath;
|
||||
};
|
||||
|
||||
#endif // QT_PROJECT_WIZZARD_CONTENT_PREFERENCES_H
|
||||
|
||||
@@ -59,18 +59,22 @@ void JavaParser::parseFiles(const std::vector<FilePath>& filePaths, const Argume
|
||||
|
||||
void JavaParser::parseFile(const FilePath& filePath, std::shared_ptr<TextAccess> textAccess, const Arguments& arguments)
|
||||
{
|
||||
m_currentFilePath = filePath.str();
|
||||
m_client->onFileParsed(FileSystem::getFileInfoForPath(filePath));
|
||||
std::string classPath = "";
|
||||
for (const FilePath& path: arguments.javaClassPaths)
|
||||
if (m_javaEnvironment)
|
||||
{
|
||||
classPath += path.str() + ";";
|
||||
m_currentFilePath = filePath.str();
|
||||
m_client->onFileParsed(FileSystem::getFileInfoForPath(filePath));
|
||||
std::string classPath = "";
|
||||
for (const FilePath& path: arguments.javaClassPaths)
|
||||
{
|
||||
// the separator used here should be the same as the one used in JavaIndexer.java
|
||||
classPath += path.str() + ";";
|
||||
}
|
||||
|
||||
// remove tabs because they screw with javaparser's location resolver
|
||||
std::string fileContent = utility::replace(textAccess->getText(), "\t", " ");
|
||||
|
||||
m_javaEnvironment->callStaticVoidMethod("io/coati/JavaIndexer", "processFile", m_id, filePath.str(), fileContent, classPath);
|
||||
}
|
||||
|
||||
// remove tabs because they screw with javaparser's location resolver
|
||||
std::string fileContent = utility::replace(textAccess->getText(), "\t", " ");
|
||||
|
||||
m_javaEnvironment->callStaticVoidMethod("io/coati/JavaIndexer", "processFile", m_id, filePath.str(), fileContent, classPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user