LibreOffice Module jvmfwk (master) 1
fwkbase.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <rtl/ustring.hxx>
21#include <rtl/ustrbuf.hxx>
22#include <sal/log.hxx>
23#include <libxml/xpathInternals.h>
24#include <osl/file.hxx>
25#include <osl/thread.hxx>
26#include <o3tl/string_view.hxx>
27#include "framework.hxx"
28#include <fwkutil.hxx>
29#include <elements.hxx>
30#include <fwkbase.hxx>
31
32using namespace osl;
33
34
35#define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_"
36#define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
37#define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME"
38#define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH"
39#define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH"
40#define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS"
41#define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS"
42
43namespace jfw
44{
45static bool g_bJavaSet = false;
46
47namespace {
48
49#if defined _WIN32
50 // The paths are used in libxml. On Windows, it takes UTF-8 paths.
51constexpr rtl_TextEncoding PathEncoding() { return RTL_TEXTENCODING_UTF8; }
52#else
53rtl_TextEncoding PathEncoding() { return osl_getThreadTextEncoding(); }
54#endif
55
56OString getVendorSettingsPath(OUString const & sURL)
57{
58 if (sURL.isEmpty())
59 return OString();
60 OUString sSystemPathSettings;
61 if (osl_getSystemPathFromFileURL(sURL.pData,
62 & sSystemPathSettings.pData) != osl_File_E_None)
65 "[Java framework] Error in function getVendorSettingsPath (fwkbase.cxx) ");
66 OString osSystemPathSettings = OUStringToOString(sSystemPathSettings, PathEncoding());
67 return osSystemPathSettings;
68}
69
70OUString getParam(OUString const & name)
71{
72 OUString retVal;
73 bool b = Bootstrap()->getFrom(name, retVal);
75 "jfw",
76 "Using bootstrap parameter " << name << " = \"" << retVal << "\""
77 << (b ? "" : " (undefined)"));
78 return retVal;
79}
80
81OUString getParamFirstUrl(OUString const & name)
82{
83 // Some parameters can consist of multiple URLs (separated by space
84 // characters, although trim() harmlessly also removes other white-space),
85 // of which only the first is used:
86 return getParam(name).trim().getToken(0, ' ');
87}
88
89}//blind namespace
90
91
93{
94 OUString xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings());
95 //Prepare the xml document and context
96 OString sSettingsPath = getVendorSettingsPath(xmlDocVendorSettingsFileUrl);
97 if (sSettingsPath.isEmpty())
98 {
99 OString sMsg("[Java framework] A vendor settings file was not specified."
100 "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS ".");
101 SAL_WARN( "jfw", sMsg );
103 }
104 if (sSettingsPath.isEmpty())
105 return;
106
107 m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr());
108 if (m_xmlDocVendorSettings == nullptr)
109 throw FrameworkException(
111 OString::Concat("[Java framework] Error while parsing file: ")
112 + sSettingsPath + ".");
113
115 int res = xmlXPathRegisterNs(
116 m_xmlPathContextVendorSettings, reinterpret_cast<xmlChar const *>("jf"),
117 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK));
118 if (res == -1)
120 "[Java framework] Error in constructor VendorSettings::VendorSettings() (fwkbase.cxx)");
121}
122
123VersionInfo VendorSettings::getVersionInformation(std::u16string_view sVendor) const
124{
125 OSL_ASSERT(!sVendor.empty());
126 OString osVendor = OUStringToOString(sVendor, RTL_TEXTENCODING_UTF8);
127 CXPathObjectPtr pathObject = xmlXPathEvalExpression(
128 reinterpret_cast<xmlChar const *>(
129 OString(
130 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" + osVendor
131 + "\"]/jf:minVersion").getStr()),
133 if (xmlXPathNodeSetIsEmpty(pathObject->nodesetval))
134 {
135 return {
136 {},
137#if defined MACOSX && defined __aarch64__
138 "17",
139#else
140 "1.8.0",
141#endif
142 ""};
143 }
144
145 VersionInfo aVersionInfo;
146 //Get minVersion
147 OString sExpression =
148 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
149 osVendor + "\"]/jf:minVersion";
150
151 CXPathObjectPtr xPathObjectMin =
152 xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpression.getStr()),
154 if (xmlXPathNodeSetIsEmpty(xPathObjectMin->nodesetval))
155 {
156 aVersionInfo.sMinVersion.clear();
157 }
158 else
159 {
160 CXmlCharPtr sVersion = xmlNodeListGetString(
162 xPathObjectMin->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
163 aVersionInfo.sMinVersion = sVersion;
164 }
165
166 //Get maxVersion
167 sExpression = "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
168 osVendor + "\"]/jf:maxVersion";
169 CXPathObjectPtr xPathObjectMax = xmlXPathEvalExpression(
170 reinterpret_cast<xmlChar const *>(sExpression.getStr()),
172 if (xmlXPathNodeSetIsEmpty(xPathObjectMax->nodesetval))
173 {
174 aVersionInfo.sMaxVersion.clear();
175 }
176 else
177 {
178 CXmlCharPtr sVersion = xmlNodeListGetString(
180 xPathObjectMax->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
181 aVersionInfo.sMaxVersion = sVersion;
182 }
183
184 //Get excludeVersions
185 sExpression = "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
186 osVendor + "\"]/jf:excludeVersions/jf:version";
187 CXPathObjectPtr xPathObjectVersions =
188 xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpression.getStr()),
190 if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions->nodesetval))
191 {
192 xmlNode* cur = xPathObjectVersions->nodesetval->nodeTab[0];
193 while (cur != nullptr)
194 {
195 if (cur->type == XML_ELEMENT_NODE )
196 {
197 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
198 {
199 CXmlCharPtr sVersion = xmlNodeListGetString(
200 m_xmlDocVendorSettings, cur->xmlChildrenNode, 1);
201 OUString usVersion = sVersion;
202 aVersionInfo.vecExcludeVersions.push_back(usVersion);
203 }
204 }
205 cur = cur->next;
206 }
207 }
208 return aVersionInfo;
209}
210
211::std::vector<OString> BootParams::getVMParameters()
212{
213 ::std::vector<OString> vecParams;
214
215 for (sal_Int32 i = 1; ; i++)
216 {
217 OUString sName = UNO_JAVA_JFW_PARAMETER + OUString::number(i);
218 OUString sValue;
219 if (Bootstrap()->getFrom(sName, sValue))
220 {
221 OString sParam =
222 OUStringToOString(sValue, osl_getThreadTextEncoding());
223 vecParams.push_back(sParam);
224 SAL_INFO(
225 "jfw.level2",
226 "Using bootstrap parameter " << sName << " = " << sParam);
227 }
228 else
229 break;
230 }
231 return vecParams;
232}
233
235{
236 return getParamFirstUrl("UNO_JAVA_JFW_USER_DATA");
237}
238
240{
241 return getParamFirstUrl("UNO_JAVA_JFW_SHARED_DATA");
242}
243
245{
246 OString sClassPath;
247 OUString sCP;
248 if (Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH, sCP ))
249 {
250 sClassPath = OUStringToOString(sCP, PathEncoding());
251 SAL_INFO(
252 "jfw.level2",
253 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH " = "
254 << sClassPath);
255 }
256
257 OUString sEnvCP;
258 if (Bootstrap()->getFrom( UNO_JAVA_JFW_ENV_CLASSPATH, sEnvCP ))
259 {
260 char * pCp = getenv("CLASSPATH");
261 if (pCp)
262 {
263 sClassPath += OStringChar(SAL_PATHSEPARATOR) + pCp;
264 }
265 SAL_INFO(
266 "jfw.level2",
267 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
268 " and class path is: " << (pCp ? pCp : ""));
269 }
270
271 return sClassPath;
272}
273
275{
276 OUString sVendor;
277 if (Bootstrap()->getFrom(UNO_JAVA_JFW_VENDOR_SETTINGS, sVendor))
278 {
279 //check the value of the bootstrap variable
280 jfw::FileStatus s = checkFileURL(sVendor);
281 if (s != FILE_OK)
282 {
283 //This bootstrap parameter can contain a relative URL
284 OUString sAbsoluteUrl;
285 OUString sBaseDir = getLibraryLocation();
286 if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl)
287 != File::E_None)
288 throw FrameworkException(
290 "[Java framework] Invalid value for bootstrap variable: "
292 sVendor = sAbsoluteUrl;
293 s = checkFileURL(sVendor);
295 {
296 throw FrameworkException(
298 "[Java framework] Invalid value for bootstrap variable: "
300 }
301 }
302 SAL_INFO(
303 "jfw.level2",
304 "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS " = "
305 << sVendor);
306 }
307 return sVendor;
308}
309
311{
312 OUString sJRE;
313 OUString sEnvJRE;
314 bool bJRE = Bootstrap()->getFrom(UNO_JAVA_JFW_JREHOME, sJRE);
315 bool bEnvJRE = Bootstrap()->getFrom(UNO_JAVA_JFW_ENV_JREHOME, sEnvJRE);
316
317 if (bJRE && bEnvJRE)
318 {
319 throw FrameworkException(
321 "[Java framework] Both bootstrap parameter "
323 UNO_JAVA_JFW_ENV_JREHOME" are set. However only one of them can be set."
324 "Check bootstrap parameters: environment variables, command line "
325 "arguments, rc/ini files for executable and java framework library.");
326 }
327 else if (bEnvJRE)
328 {
329 const char * pJRE = getenv("JAVA_HOME");
330 if (pJRE == nullptr)
331 {
332 throw FrameworkException(
334 "[Java framework] Both bootstrap parameter "
335 UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable "
336 "JAVA_HOME is not set.");
337 }
338 std::string_view osJRE(pJRE);
339 OUString usJRE = OStringToOUString(osJRE, osl_getThreadTextEncoding());
340 if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None)
341 throw FrameworkException(
343 "[Java framework] Error in function BootParams::getJREHome() "
344 "(fwkbase.cxx).");
345 SAL_INFO(
346 "jfw.level2",
347 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_JREHOME
348 " with JAVA_HOME = " << pJRE);
349 }
350 else if (getMode() == JFW_MODE_DIRECT && !bJRE)
351 {
352 throw FrameworkException(
354 "[Java framework] The bootstrap parameter "
356 " must be set in direct mode.");
357 }
358
360 bJRE, "jfw.level2",
361 "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME " = " << sJRE);
362 return sJRE;
363}
364
366{
367 OUString sParams;
368 Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH_URLS, sParams);
369 SAL_INFO(
370 "jfw.level2",
371 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS " = "
372 << sParams);
373 return sParams;
374}
375
377{
378 static bool g_bMode = false;
379 static JFW_MODE g_mode = JFW_MODE_APPLICATION;
380
381 if (!g_bMode)
382 {
383 //check if either of the "direct mode" bootstrap variables is set
384 bool bDirectMode = true;
385 OUString sValue;
386 const rtl::Bootstrap * aBoot = Bootstrap();
387 if (!aBoot->getFrom(UNO_JAVA_JFW_JREHOME, sValue))
388 {
389 if (!aBoot->getFrom(UNO_JAVA_JFW_ENV_JREHOME, sValue))
390 {
391 if (!aBoot->getFrom(UNO_JAVA_JFW_CLASSPATH, sValue))
392 {
393 if (!aBoot->getFrom(UNO_JAVA_JFW_ENV_CLASSPATH, sValue))
394 {
395 OUString sParams = UNO_JAVA_JFW_PARAMETER +
396 OUString::number(1);
397 if (!aBoot->getFrom(sParams, sValue))
398 {
399 bDirectMode = false;
400 }
401 }
402 }
403 }
404 }
405
406 if (bDirectMode)
407 g_mode = JFW_MODE_DIRECT;
408 else
409 g_mode = JFW_MODE_APPLICATION;
410 g_bMode = true;
411 }
412
413 return g_mode;
414}
415
417{
418 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION);
419 OUString sParams = BootParams::getClasspathUrls();
420 if (sParams.isEmpty())
421 return OUString();
422
423 OUStringBuffer buf;
424 sal_Int32 index = 0;
425 do
426 {
427 OUString token( o3tl::trim(o3tl::getToken(sParams, 0, ' ', index )) );
428 if (!token.isEmpty())
429 {
430 OUString systemPathElement;
431 oslFileError rc = osl_getSystemPathFromFileURL(
432 token.pData, &systemPathElement.pData );
433 OSL_ASSERT( rc == osl_File_E_None );
434 if (rc == osl_File_E_None && !systemPathElement.isEmpty())
435 {
436 if (buf.getLength() > 0)
437 buf.append( SAL_PATHSEPARATOR );
438 buf.append( systemPathElement );
439 }
440 }
441 }
442 while (index >= 0);
443 return buf.makeStringAndClear();
444}
445
446OString makeClassPathOption(std::u16string_view sUserClassPath)
447{
448 //Compose the class path
449 OString sPaths;
450 OUStringBuffer sBufCP(4096);
451
452 // append all user selected jars to the class path
453 if (!sUserClassPath.empty())
454 sBufCP.append(sUserClassPath);
455
456 //append all jar libraries and components to the class path
457 OUString sAppCP = getApplicationClassPath();
458 if (!sAppCP.isEmpty())
459 {
460 if (!sUserClassPath.empty())
461 {
462 sBufCP.append(SAL_PATHSEPARATOR);
463 }
464 sBufCP.append(sAppCP);
465 }
466
467 sPaths = OUStringToOString(sBufCP, PathEncoding());
468 if (sPaths.isEmpty()) {
469 return "";
470 }
471
472 OString sOptionClassPath = "-Djava.class.path=" + sPaths;
473 return sOptionClassPath;
474}
475
477{
479}
480
482{
484}
485
486OString getSettingsPath( const OUString & sURL)
487{
488 if (sURL.isEmpty())
489 return OString();
490 OUString sPath;
491 if (osl_getSystemPathFromFileURL(sURL.pData,
492 & sPath.pData) != osl_File_E_None)
493 throw FrameworkException(
495 "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx).");
496 return OUStringToOString(sPath, PathEncoding());
497}
498
500{
502}
503
505{
506 g_bJavaSet = true;
507}
508
510{
511 //g_setJavaProcId not set means no Java selected
512 return g_bJavaSet;
513}
514
515
516}
517
518/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
CXPathContextPtr m_xmlPathContextVendorSettings
Definition: fwkbase.hxx:37
CXmlDocPtr m_xmlDocVendorSettings
Definition: fwkbase.hxx:36
VersionInfo getVersionInformation(std::u16string_view sVendor) const
Definition: fwkbase.cxx:123
#define SAL_PATHSEPARATOR
#define NS_JAVA_FRAMEWORK
Definition: elements.hxx:34
OUString sName
#define UNO_JAVA_JFW_CLASSPATH_URLS
Definition: fwkbase.cxx:40
#define UNO_JAVA_JFW_JREHOME
Definition: fwkbase.cxx:36
#define UNO_JAVA_JFW_VENDOR_SETTINGS
Definition: fwkbase.cxx:41
#define UNO_JAVA_JFW_ENV_CLASSPATH
Definition: fwkbase.cxx:39
#define UNO_JAVA_JFW_PARAMETER
Definition: fwkbase.cxx:35
#define UNO_JAVA_JFW_CLASSPATH
Definition: fwkbase.cxx:38
#define UNO_JAVA_JFW_ENV_JREHOME
Definition: fwkbase.cxx:37
const char * name
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
int i
OUString getJREHome()
Definition: fwkbase.cxx:310
::std::vector< OString > getVMParameters()
Definition: fwkbase.cxx:211
OString getClasspath()
Definition: fwkbase.cxx:244
OUString getClasspathUrls()
Definition: fwkbase.cxx:365
OUString getVendorSettings()
Definition: fwkbase.cxx:274
OUString getSharedData()
Definition: fwkbase.cxx:239
OUString getUserData()
Definition: fwkbase.cxx:234
Definition: elements.cxx:47
OString getSettingsPath(const OUString &sURL)
Definition: fwkbase.cxx:486
const rtl::Bootstrap * Bootstrap()
provides a bootstrap class which already knows the values from the jvmfkwrc file.
Definition: fwkutil.cxx:47
void setJavaSelected()
Called from writeJavaInfoData.
Definition: fwkbase.cxx:504
OUString getApplicationClassPath()
Definition: fwkbase.cxx:416
bool wasJavaSelectedInSameProcess()
Determines if the currently selected Java was set in this process.
Definition: fwkbase.cxx:509
static bool g_bJavaSet
Definition: fwkbase.cxx:45
OString getSharedSettingsPath()
Returns the system path of the share settings file.
Definition: fwkbase.cxx:481
JFW_MODE getMode()
Definition: fwkbase.cxx:376
JFW_MODE
Definition: fwkbase.hxx:76
@ JFW_MODE_APPLICATION
Definition: fwkbase.hxx:77
@ JFW_MODE_DIRECT
Definition: fwkbase.hxx:79
OString makeClassPathOption(std::u16string_view sUserClassPath)
creates the -Djava.class.path option with the complete classpath, including the paths which are set b...
Definition: fwkbase.cxx:446
OString getVendorSettingsPath()
Definition: fwkbase.cxx:499
jfw::FileStatus checkFileURL(const OUString &sURL)
checks if the URL is a file.
Definition: fwkutil.cxx:158
OUString getLibraryLocation()
Returns the file URL of the directory where the framework library (this library) resides.
Definition: fwkutil.cxx:145
OString getUserSettingsPath()
Get the system path to the javasettings.xml Converts the URL returned from getUserSettingsURL to a Sy...
Definition: fwkbase.cxx:476
FileStatus
Definition: fwkutil.hxx:52
@ FILE_OK
Definition: fwkutil.hxx:53
@ FILE_DOES_NOT_EXIST
Definition: fwkutil.hxx:54
@ FILE_INVALID
Definition: fwkutil.hxx:55
index
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
::std::vector< OUString > vecExcludeVersions
Definition: elements.hxx:321
OUString sMinVersion
Definition: elements.hxx:322
OUString sMaxVersion
Definition: elements.hxx:323