diff options
author | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2023-06-12 14:31:45 +0200 |
---|---|---|
committer | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2023-06-21 21:46:58 +0200 |
commit | c71b6f2d52f7df0d7f91524fc161979fc0912e0e (patch) | |
tree | bd59e824bab98a42fdf8bb4cf351cebc563d1301 | |
parent | 67232f226438a9e73beab9dec90f1a3739088b57 (diff) |
Allow bootstrap variables in Java user classpath settings, 2nd try
Add a second mode: When a classpath starts with '$', bootstrap variables are recognized.
The classpath must then be provided as URL, not native path.
Change-Id: Idcc229a2b4e9a512b0e712ea932a6e4293907db3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152899
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
-rw-r--r-- | cui/source/options/optjava.cxx | 19 | ||||
-rw-r--r-- | include/jvmfwk/framework.hxx | 11 | ||||
-rw-r--r-- | jvmfwk/source/framework.cxx | 53 |
3 files changed, 76 insertions, 7 deletions
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx index 36540800bb62..cd09bc3a9254 100644 --- a/cui/source/options/optjava.cxx +++ b/cui/source/options/optjava.cxx @@ -34,6 +34,7 @@ #include <officecfg/Office/Common.hxx> #include <osl/file.hxx> #include <svtools/miscopt.hxx> +#include <rtl/bootstrap.hxx> #include <strings.hrc> #include <vcl/svapp.hxx> @@ -935,16 +936,22 @@ void SvxJavaClassPathDlg::SetClassPath( const OUString& _rPath ) m_xPathList->clear(); if (!_rPath.isEmpty()) { - sal_Int32 nIdx = 0; - do + std::vector paths = jfw_convertUserPathList(_rPath); + for (auto const& path : paths) { - OUString sToken = _rPath.getToken( 0, CLASSPATH_DELIMITER, nIdx ); OUString sURL; - osl::FileBase::getFileURLFromSystemPath(sToken, sURL); // best effort + if (path.startsWith("$")) + { + sURL = path; + rtl::Bootstrap::expandMacros(sURL); + } + else + { + osl::FileBase::getFileURLFromSystemPath(path, sURL); + } INetURLObject aURL( sURL ); - m_xPathList->append("", sToken, SvFileInformationManager::GetImageId(aURL)); + m_xPathList->append("", path, SvFileInformationManager::GetImageId(aURL)); } - while (nIdx>=0); // select first entry m_xPathList->select(0); } diff --git a/include/jvmfwk/framework.hxx b/include/jvmfwk/framework.hxx index 3c7fe2981436..1726f8e47921 100644 --- a/include/jvmfwk/framework.hxx +++ b/include/jvmfwk/framework.hxx @@ -387,6 +387,17 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAndSelectJRE(std::unique_ptr<JavaInf JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAllJREs( std::vector<std::unique_ptr<JavaInfo>> *parInfo); +/** + * Convert colon-separated userClassPath which might contain bootstrap variables + * (which also might contain colons) to a list of classPaths, keeping bootstrap variables intact. + * + * FIXME: Nested or multiple occurrences of ${...:...:...} are currently not supported. + * + * @param sUserPath colon-separated string of user classpaths + * @return list of user classpaths + */ +JVMFWK_DLLPUBLIC std::vector<OUString> jfw_convertUserPathList(OUString const& sUserPath); + /** determines if a path points to a Java installation. <p>If the path belongs to a JRE installation then it returns the diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx index 07916b867356..6c40ca1de3a8 100644 --- a/jvmfwk/source/framework.cxx +++ b/jvmfwk/source/framework.cxx @@ -23,6 +23,7 @@ #include <cassert> #include <memory> +#include <rtl/bootstrap.hxx> #include <rtl/ref.hxx> #include <rtl/ustring.hxx> #include <osl/diagnose.h> @@ -123,6 +124,40 @@ javaFrameworkError jfw_findAllJREs(std::vector<std::unique_ptr<JavaInfo>> *pparI } } +std::vector<OUString> jfw_convertUserPathList(OUString const& sUserPath) +{ + std::vector<OUString> result; + sal_Int32 nIdx = 0; + do + { + sal_Int32 nextColon = sUserPath.indexOf(SAL_PATHSEPARATOR, nIdx); + OUString sToken(sUserPath.copy(nIdx, nextColon > 0 ? nextColon - nIdx + : sUserPath.getLength() - nIdx)); + + // Check if we are in bootstrap variable mode (class path starts with '$'). + // Then the class path must be in URL format. + if (sToken.startsWith("$")) + { + // Detect open bootstrap variables - they might contain colons - we need to skip those. + sal_Int32 nBootstrapVarStart = sToken.indexOf("${"); + if (nBootstrapVarStart >= 0) + { + sal_Int32 nBootstrapVarEnd = sToken.indexOf("}", nBootstrapVarStart); + if (nBootstrapVarEnd == -1) + { + // Current colon is part of bootstrap variable - skip it! + nextColon = sUserPath.indexOf(SAL_PATHSEPARATOR, nextColon + 1); + sToken = sUserPath.copy(nIdx, nextColon > 0 ? nextColon - nIdx + : sUserPath.getLength() - nIdx); + } + } + } + result.emplace_back(sToken); + nIdx = nextColon + 1; + } while (nIdx > 0); + return result; +} + javaFrameworkError jfw_startVM( JavaInfo const * pInfo, std::vector<OUString> const & arOptions, JavaVM ** ppVM, JNIEnv ** ppEnv) @@ -202,7 +237,23 @@ javaFrameworkError jfw_startVM( return JFW_E_NEED_RESTART; vmParams = settings.getVmParametersUtf8(); - sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath()); + // Expand user classpath (might contain bootstrap vars) + OUString sUserPath(settings.getUserClassPath()); + std::vector paths = jfw_convertUserPathList(sUserPath); + OUString sUserPathExpanded; + for (auto& path : paths) + { + if (!sUserPathExpanded.isEmpty()) + sUserPathExpanded += OUStringChar(SAL_PATHSEPARATOR); + if (path.startsWith("$")) + { + OUString sURL = path; + rtl::Bootstrap::expandMacros(sURL); + osl::FileBase::getSystemPathFromFileURL(sURL, path); + } + sUserPathExpanded += path; + } + sUserClassPath = jfw::makeClassPathOption(sUserPathExpanded); } // end mode FWK_MODE_OFFICE else if (mode == jfw::JFW_MODE_DIRECT) { |