logic: revised loading Java library

* implemented a dynamic way (that does not involve the linker) to load the Java runtime library
* implemented JavaPathDetectorLinux
* Filepicker for Java runtime library now asks to pick JVM library instead of folder
* extended error handling for JavaEnvironmentFactory
This commit is contained in:
malte_langkabel
2016-08-31 12:16:29 +02:00
parent eb621eea33
commit d2de395ed5
16 changed files with 313 additions and 133 deletions
+2
View File
@@ -176,6 +176,8 @@ add_files(
utility/path_detector/java_runtime/JavaPathDetector.cpp
utility/path_detector/java_runtime/JavaPathDetector.h
utility/path_detector/java_runtime/JavaPathDetectorLinux.cpp
utility/path_detector/java_runtime/JavaPathDetectorLinux.h
utility/path_detector/java_runtime/JavaPathDetectorMac.cpp
utility/path_detector/java_runtime/JavaPathDetectorMac.h
utility/path_detector/java_runtime/JavaPathDetectorWindows.cpp
@@ -3,6 +3,7 @@
#include "settings/ApplicationSettings.h"
#include "utility/file/FileSystem.h"
#include "utility/messaging/type/MessageSwitchColorScheme.h"
#include "utility/path_detector/java_runtime/JavaPathDetectorLinux.h"
#include "utility/path_detector/java_runtime/JavaPathDetectorMac.h"
#include "utility/path_detector/java_runtime/JavaPathDetectorWindows.h"
#include "utility/ResourcePaths.h"
@@ -176,45 +177,57 @@ void QtProjectWizzardContentPreferences::populate(QGridLayout* layout, int& row)
layout->setRowMinimumHeight(row++, 20);
// Java
layout->addWidget(createFormTitle("JAVA"), row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignLeft);
row++;
// java path
// jvm library path
m_javaPath = new QtLocationPicker(this);
m_javaPath->setPickDirectory(true);
#ifdef _WIN32
QString filter = "JVM Library (jvm.dll)";
#elif __APPLE__
QString filter = "JVM Library (libjvm.dylib)";
#else
QString filter = "JVM Library (libjvm.so)";
#endif
m_javaPath->setFileFilter(filter);
if (QSysInfo::windowsVersion() != QSysInfo::WV_None)
{
m_javaPath->setPlaceholderText("<jre_8_root>/bin/client");
m_javaPath->setPlaceholderText("<jre_path>/bin/client/jvm.dll");
}
else if (QSysInfo::macVersion() != QSysInfo::MV_None)
{
m_javaPath->setPlaceholderText("<jre_8_root>/Contents/Home");
m_javaPath->setPlaceholderText("<jre_path>Contents/Home/jre/lib/server/libjvm.dylib");
}
else
{
m_javaPath->setPlaceholderText("<jre_path>/bin/<arch>/server/libjvm.so");
}
layout->addWidget(createFormLabel("Java Path"), row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignRight);
layout->addWidget(m_javaPath, row, QtProjectWizzardWindow::BACK_COL);
addHelpButton(
"Location of the folder that contains the dynamic library for your jre virtual machine."
"Location of the dynamic library for your jre virtual machine."
, layout, row
);
row++;
m_javaPathDetector = std::make_shared<CombinedPathDetector>();
if (QSysInfo::windowsVersion() != QSysInfo::WV_None)
{
m_javaPathDetector = std::make_shared<CombinedPathDetector>();
m_javaPathDetector->addDetector(std::make_shared<JavaPathDetectorWindows>("1.8"));
addJavaPathDetection(layout, row);
}
else if (QSysInfo::macVersion() != QSysInfo::MV_None)
{
m_javaPathDetector = std::make_shared<CombinedPathDetector>();
m_javaPathDetector->addDetector(std::make_shared<JavaPathDetectorMac>("1.8"));
addJavaPathDetection(layout, row);
}
else
{
m_javaPathDetector->addDetector(std::make_shared<JavaPathDetectorLinux>("1.8"));
}
addJavaPathDetection(layout, row);
layout->setRowMinimumHeight(row++, 20);
@@ -0,0 +1,128 @@
#include "utility/path_detector/java_runtime/JavaPathDetectorLinux.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
#ifdef __x86_64__
const std::string arch = "amd64";
#else
const std::string arch = "i386";
#endif
const std::string jvmLibPathRelativeToJavaExecutable = "/../lib/" + arch + "/server/libjvm.so";
JavaPathDetectorLinux::JavaPathDetectorLinux(const std::string javaVersion)
: JavaPathDetector("Java " + javaVersion + " for Linux", javaVersion)
{
}
JavaPathDetectorLinux::~JavaPathDetectorLinux()
{
}
FilePath JavaPathDetectorLinux::getJavaInPath() const
{
std::string command = "which java";
std::string output = utility::executeProcess(command.c_str());
if (output.size())
{
output = utility::trim(output);
FilePath javaPath(output);
if (!javaPath.empty() && javaPath.exists())
{
return javaPath;
}
}
return FilePath();
}
FilePath JavaPathDetectorLinux::readLink(const FilePath& path) const
{
std::string command = "readlink -f " + path.str();
FilePath javaPath( utility::executeProcess(command.c_str()));
if ( !javaPath.empty() )
{
return javaPath;
}
return FilePath();
}
FilePath JavaPathDetectorLinux::getFilePathRelativeToJavaExecutable(FilePath& javaExecutablePath) const
{
FilePath p(javaExecutablePath.parentDirectory().str() + jvmLibPathRelativeToJavaExecutable);
if ( p.exists() )
{
return p.canonical();
}
else
{
return FilePath();
}
}
FilePath JavaPathDetectorLinux::getJavaInJavaHome() const
{
std::string command = "";
char* p = getenv("JAVA_HOME");
if ( p == nullptr )
{
return FilePath();
}
FilePath javaPath(std::string(p) + "/bin/java");
if ( !javaPath.empty() && javaPath.exists() )
{
return javaPath;
}
return FilePath();
}
bool JavaPathDetectorLinux::checkVersion(const FilePath& path) const
{
std::string command = path.str() + " -version";
std::string output = utility::executeProcess(command.c_str());
return output.find(m_javaVersion) != std::string::npos;
}
std::vector<FilePath> JavaPathDetectorLinux::getPaths() const
{
std::vector<FilePath> paths;
FilePath p = getJavaInPath();
if( !p.empty() )
{
paths.push_back(p);
}
p = getJavaInJavaHome();
if( !p.empty() )
{
paths.push_back(p);
}
// some default paths for java
paths.push_back(FilePath("/etc/alternatives/java"));
paths.push_back(FilePath("/usr/lib/jvm/default/bin/java"));
paths.push_back(FilePath("/usr/lib/jvm/java-openjdk/bin/java"));
for ( FilePath path : paths )
{
if (checkVersion(path))
{
FilePath absoluteJavaPath = readLink(path);
FilePath jvmLibrary = getFilePathRelativeToJavaExecutable(absoluteJavaPath);
if (jvmLibrary.exists())
{
std::vector<FilePath> foundPath = { jvmLibrary };
return foundPath;
}
}
}
return std::vector<FilePath>();
}
@@ -0,0 +1,24 @@
#ifndef JAVA_PATH_DETECTOR_LINUX_H
#define JAVA_PATH_DETECTOR_LINUX_H
#include "utility/path_detector/java_runtime/JavaPathDetector.h"
class JavaPathDetectorLinux
: public JavaPathDetector
{
public:
JavaPathDetectorLinux(const std::string javaVersion);
virtual ~JavaPathDetectorLinux();
virtual std::vector<FilePath> getPaths() const;
private:
FilePath getJavaInPath() const;
FilePath readLink(const FilePath& path) const;
FilePath getJavaInJavaHome() const;
bool checkVersion(const FilePath& path) const;
FilePath getFilePathRelativeToJavaExecutable(FilePath& javaExecutablePath) const;
};
#endif // JAVA_PATH_DETECTOR_LINUX_H
@@ -15,19 +15,24 @@ JavaPathDetectorMac::~JavaPathDetectorMac()
std::vector<FilePath> JavaPathDetectorMac::getPaths() const
{
std::vector<FilePath> paths;
FilePath javaPath;
std::string command = "/usr/libexec/java_home";
std::string output = utility::executeProcess(command.c_str());
if (output.size())
{
output = utility::trim(output);
javaPath = FilePath(utility::trim(output) + "/jre/lib/server/libjvm.dylib");
}
FilePath javaPath(output);
if (!javaPath.empty() && javaPath.exists())
{
paths.push_back(javaPath);
}
if (!javaPath.exists())
{
javaPath = FilePath("/usr/lib/libjvm.dylib");
}
if (javaPath.exists())
{
paths.push_back(javaPath);
}
return paths;
@@ -28,7 +28,7 @@ std::vector<FilePath> JavaPathDetectorWindows::getPaths() const
std::vector<FilePath> paths;
if (path.exists())
{
paths.push_back(path.parentDirectory());
paths.push_back(path);
}
return paths;
}
+2
View File
@@ -1,6 +1,7 @@
#include "utility/utilityApp.h"
#include <QProcess>
#include "utility/utilityString.h"
std::string utility::executeProcess(const char *cmd)
{
@@ -10,6 +11,7 @@ std::string utility::executeProcess(const char *cmd)
process.waitForFinished();
std::string processoutput = process.readAll().toStdString();
process.close();
processoutput = utility::trim(processoutput);
return processoutput;
}