2013-11-24 11:06:16 +05:30
|
|
|
#include "JavaChecker.h"
|
2021-11-22 03:51:12 +05:30
|
|
|
|
2013-11-24 11:06:16 +05:30
|
|
|
#include <QFile>
|
|
|
|
#include <QProcess>
|
2013-12-11 09:24:39 +05:30
|
|
|
#include <QMap>
|
2015-02-02 05:39:28 +05:30
|
|
|
#include <QDebug>
|
2013-11-24 11:06:16 +05:30
|
|
|
|
2021-11-22 03:51:12 +05:30
|
|
|
#include "JavaUtils.h"
|
|
|
|
#include "FileSystem.h"
|
|
|
|
#include "Commandline.h"
|
|
|
|
#include "Application.h"
|
2017-05-13 04:54:15 +05:30
|
|
|
|
2013-11-24 11:06:16 +05:30
|
|
|
JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-12-11 09:24:39 +05:30
|
|
|
void JavaChecker::performCheck()
|
2013-11-24 11:06:16 +05:30
|
|
|
{
|
2022-06-15 01:30:24 +05:30
|
|
|
QString checkerJar = JavaUtils::getJavaCheckPath();
|
|
|
|
|
|
|
|
if (checkerJar.isEmpty())
|
|
|
|
{
|
|
|
|
qDebug() << "Java checker library could not be found. Please check your installation.";
|
|
|
|
return;
|
|
|
|
}
|
2018-07-15 18:21:05 +05:30
|
|
|
|
|
|
|
QStringList args;
|
|
|
|
|
|
|
|
process.reset(new QProcess());
|
|
|
|
if(m_args.size())
|
|
|
|
{
|
|
|
|
auto extraArgs = Commandline::splitArgs(m_args);
|
|
|
|
args.append(extraArgs);
|
|
|
|
}
|
|
|
|
if(m_minMem != 0)
|
|
|
|
{
|
|
|
|
args << QString("-Xms%1m").arg(m_minMem);
|
|
|
|
}
|
|
|
|
if(m_maxMem != 0)
|
|
|
|
{
|
|
|
|
args << QString("-Xmx%1m").arg(m_maxMem);
|
|
|
|
}
|
|
|
|
if(m_permGen != 64)
|
|
|
|
{
|
|
|
|
args << QString("-XX:PermSize=%1m").arg(m_permGen);
|
|
|
|
}
|
|
|
|
|
|
|
|
args.append({"-jar", checkerJar});
|
|
|
|
process->setArguments(args);
|
|
|
|
process->setProgram(m_path);
|
|
|
|
process->setProcessChannelMode(QProcess::SeparateChannels);
|
|
|
|
process->setProcessEnvironment(CleanEnviroment());
|
|
|
|
qDebug() << "Running java checker: " + m_path + args.join(" ");;
|
|
|
|
|
|
|
|
connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
|
|
|
|
connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
|
|
|
|
connect(process.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(stdoutReady()));
|
|
|
|
connect(process.get(), SIGNAL(readyReadStandardError()), this, SLOT(stderrReady()));
|
|
|
|
connect(&killTimer, SIGNAL(timeout()), SLOT(timeout()));
|
|
|
|
killTimer.setSingleShot(true);
|
|
|
|
killTimer.start(15000);
|
|
|
|
process->start();
|
2013-11-24 11:06:16 +05:30
|
|
|
}
|
|
|
|
|
2015-05-04 04:50:48 +05:30
|
|
|
void JavaChecker::stdoutReady()
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
QByteArray data = process->readAllStandardOutput();
|
|
|
|
QString added = QString::fromLocal8Bit(data);
|
|
|
|
added.remove('\r');
|
|
|
|
m_stdout += added;
|
2015-05-04 04:50:48 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
void JavaChecker::stderrReady()
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
QByteArray data = process->readAllStandardError();
|
|
|
|
QString added = QString::fromLocal8Bit(data);
|
|
|
|
added.remove('\r');
|
|
|
|
m_stderr += added;
|
2015-05-04 04:50:48 +05:30
|
|
|
}
|
|
|
|
|
2013-11-24 11:06:16 +05:30
|
|
|
void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
killTimer.stop();
|
2019-04-08 03:29:04 +05:30
|
|
|
QProcessPtr _process = process;
|
|
|
|
process.reset();
|
2018-07-15 18:21:05 +05:30
|
|
|
|
|
|
|
JavaCheckResult result;
|
|
|
|
{
|
|
|
|
result.path = m_path;
|
|
|
|
result.id = m_id;
|
|
|
|
}
|
|
|
|
result.errorLog = m_stderr;
|
|
|
|
result.outLog = m_stdout;
|
|
|
|
qDebug() << "STDOUT" << m_stdout;
|
|
|
|
qWarning() << "STDERR" << m_stderr;
|
|
|
|
qDebug() << "Java checker finished with status " << status << " exit code " << exitcode;
|
|
|
|
|
|
|
|
if (status == QProcess::CrashExit || exitcode == 1)
|
|
|
|
{
|
|
|
|
result.validity = JavaCheckResult::Validity::Errored;
|
|
|
|
emit checkFinished(result);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
QMap<QString, QString> results;
|
2022-05-02 22:40:45 +05:30
|
|
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
|
|
|
QStringList lines = m_stdout.split("\n", Qt::SkipEmptyParts);
|
|
|
|
#else
|
2018-07-15 18:21:05 +05:30
|
|
|
QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
|
2022-05-02 22:40:45 +05:30
|
|
|
#endif
|
2018-07-15 18:21:05 +05:30
|
|
|
for(QString line : lines)
|
|
|
|
{
|
|
|
|
line = line.trimmed();
|
2022-01-08 16:56:16 +05:30
|
|
|
// NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux
|
|
|
|
if (line.contains("/bedrock/strata")) {
|
|
|
|
continue;
|
|
|
|
}
|
2018-07-15 18:21:05 +05:30
|
|
|
|
2022-05-02 22:40:45 +05:30
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
|
|
|
auto parts = line.split('=', Qt::SkipEmptyParts);
|
|
|
|
#else
|
2018-07-15 18:21:05 +05:30
|
|
|
auto parts = line.split('=', QString::SkipEmptyParts);
|
2022-05-02 22:40:45 +05:30
|
|
|
#endif
|
2018-07-15 18:21:05 +05:30
|
|
|
if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
|
|
|
|
{
|
2022-01-16 16:35:40 +05:30
|
|
|
continue;
|
2018-07-15 18:21:05 +05:30
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
results.insert(parts[0], parts[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-08 01:58:41 +05:30
|
|
|
if(!results.contains("os.arch") || !results.contains("java.version") || !results.contains("java.vendor") || !success)
|
2018-07-15 18:21:05 +05:30
|
|
|
{
|
|
|
|
result.validity = JavaCheckResult::Validity::ReturnedInvalidData;
|
|
|
|
emit checkFinished(result);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto os_arch = results["os.arch"];
|
|
|
|
auto java_version = results["java.version"];
|
2020-09-08 01:58:41 +05:30
|
|
|
auto java_vendor = results["java.vendor"];
|
2022-02-19 21:17:34 +05:30
|
|
|
bool is_64 = os_arch == "x86_64" || os_arch == "amd64" || os_arch == "aarch64" || os_arch == "arm64";
|
2018-07-15 18:21:05 +05:30
|
|
|
|
|
|
|
|
|
|
|
result.validity = JavaCheckResult::Validity::Valid;
|
|
|
|
result.is_64bit = is_64;
|
|
|
|
result.mojangPlatform = is_64 ? "64" : "32";
|
|
|
|
result.realPlatform = os_arch;
|
|
|
|
result.javaVersion = java_version;
|
2020-09-08 01:58:41 +05:30
|
|
|
result.javaVendor = java_vendor;
|
2018-07-15 18:21:05 +05:30
|
|
|
qDebug() << "Java checker succeeded.";
|
|
|
|
emit checkFinished(result);
|
2013-11-24 11:06:16 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
void JavaChecker::error(QProcess::ProcessError err)
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
if(err == QProcess::FailedToStart)
|
|
|
|
{
|
|
|
|
qDebug() << "Java checker has failed to start.";
|
2021-10-25 15:30:25 +05:30
|
|
|
qDebug() << "Process environment:";
|
|
|
|
qDebug() << process->environment();
|
|
|
|
qDebug() << "Native environment:";
|
|
|
|
qDebug() << QProcessEnvironment::systemEnvironment().toStringList();
|
|
|
|
killTimer.stop();
|
2018-07-15 18:21:05 +05:30
|
|
|
JavaCheckResult result;
|
|
|
|
{
|
|
|
|
result.path = m_path;
|
|
|
|
result.id = m_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
emit checkFinished(result);
|
|
|
|
return;
|
|
|
|
}
|
2013-11-24 11:06:16 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
void JavaChecker::timeout()
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
// NO MERCY. NO ABUSE.
|
|
|
|
if(process)
|
|
|
|
{
|
|
|
|
qDebug() << "Java checker has been killed by timeout.";
|
|
|
|
process->kill();
|
|
|
|
}
|
2013-11-24 11:06:16 +05:30
|
|
|
}
|