LibreOffice Module stoc (master) 1
javavm.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
21#include "javavm.hxx"
22
23#include "interact.hxx"
24#include "jvmargs.hxx"
25
26#include <com/sun/star/beans/NamedValue.hpp>
27#include <com/sun/star/container/XContainer.hpp>
28#include <com/sun/star/java/JavaNotFoundException.hpp>
29#include <com/sun/star/java/InvalidJavaSettingsException.hpp>
30#include <com/sun/star/java/RestartRequiredException.hpp>
31#include <com/sun/star/java/JavaDisabledException.hpp>
32#include <com/sun/star/java/JavaVMCreationFailureException.hpp>
33#include <com/sun/star/lang/DisposedException.hpp>
34#include <com/sun/star/lang/IllegalArgumentException.hpp>
35#include <com/sun/star/lang/XMultiComponentFactory.hpp>
36#include <com/sun/star/lang/XMultiServiceFactory.hpp>
37#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
38#include <com/sun/star/registry/XRegistryKey.hpp>
39#include <com/sun/star/registry/XSimpleRegistry.hpp>
40#include <com/sun/star/task/XInteractionHandler.hpp>
41#include <com/sun/star/uno/Exception.hpp>
42#include <com/sun/star/uno/Reference.hxx>
43#include <com/sun/star/uno/RuntimeException.hpp>
44#include <com/sun/star/uno/Sequence.hxx>
45#include <com/sun/star/uno/XComponentContext.hpp>
46#include <com/sun/star/uno/XCurrentContext.hpp>
47#include <com/sun/star/uno/XInterface.hpp>
48#include <com/sun/star/util/theMacroExpander.hpp>
53#include <cppuhelper/weak.hxx>
57#include <rtl/process.h>
58#include <rtl/ustring.hxx>
59#include <sal/types.h>
60#include <sal/log.hxx>
61#include <uno/current_context.hxx>
62#include <jvmfwk/framework.hxx>
64#include <jni.h>
65
66#include <stack>
67#include <string.h>
68#include <time.h>
69#include <memory>
70#include <utility>
71#include <vector>
72
73// Properties of the javavm can be put
74// as a comma separated list in this
75// environment variable
76#ifdef UNIX
77#define TIMEZONE "MEZ"
78#else
79#define TIMEZONE "MET"
80#endif
81
82/* Within this implementation of the com.sun.star.java.JavaVirtualMachine
83 * service and com.sun.star.java.theJavaVirtualMachine singleton, the method
84 * com.sun.star.java.XJavaVM.getJavaVM relies on the following:
85 * 1 The string "$URE_INTERNAL_JAVA_DIR/" is expanded via the
86 * com.sun.star.util.theMacroExpander singleton into an internal (see the
87 * com.sun.star.uri.ExternalUriReferenceTranslator service), hierarchical URI
88 * reference relative to which the URE JAR files can be addressed.
89 * 2 The string "$URE_INTERNAL_JAVA_CLASSPATH" is either not expandable via the
90 * com.sun.star.util.theMacroExpander singleton
91 * (com.sun.star.lang.IllegalArgumentException), or is expanded via the
92 * com.sun.star.util.theMacroExpander singleton into a list of zero or more
93 * internal (see the com.sun.star.uri.ExternalUriReferenceTranslator service)
94 * URIs, where any space characters (U+0020) are ignored (and, in particular,
95 * separate adjacent URIs).
96 * If either of these requirements is not met, getJavaVM raises a
97 * com.sun.star.uno.RuntimeException.
98 */
99
101
102namespace {
103
104
105class NoJavaIniException: public css::uno::Exception
106{
107};
108
109typedef std::stack< jvmaccess::VirtualMachine::AttachGuard * > GuardStack;
110
111extern "C" {
112
113static void destroyAttachGuards(void * pData)
114{
115 GuardStack * pStack = static_cast< GuardStack * >(pData);
116 if (pStack != nullptr)
117 {
118 while (!pStack->empty())
119 {
120 delete pStack->top();
121 pStack->pop();
122 }
123 delete pStack;
124 }
125}
126
127}
128
129bool askForRetry(css::uno::Any const & rException)
130{
131 css::uno::Reference< css::uno::XCurrentContext > xContext(
132 css::uno::getCurrentContext());
133 if (xContext.is())
134 {
135 css::uno::Reference< css::task::XInteractionHandler > xHandler;
136 xContext->getValueByName("java-vm.interaction-handler")
137 >>= xHandler;
138 if (xHandler.is())
139 {
141 new stoc_javavm::InteractionRequest(rException));
142 xHandler->handle(xRequest);
143 return xRequest->retry();
144 }
145 }
146 return false;
147}
148
149// Only gets the properties if the "Proxy Server" entry in the option dialog is
150// set to manual (i.e. not to none)
152void getINetPropsFromConfig(stoc_javavm::JVM * pjvm,
153 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
154 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
155{
156 css::uno::Reference<css::uno::XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
157 "com.sun.star.configuration.ConfigurationRegistry",
158 xCtx );
159 if(!xConfRegistry.is()) throw css::uno::RuntimeException("javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
160
161 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(xConfRegistry, css::uno::UNO_QUERY_THROW);
162 xConfRegistry_simple->open("org.openoffice.Inet", true, false);
163 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
164
165// if ooInetProxyType is not 0 then read the settings
166 css::uno::Reference<css::registry::XRegistryKey> proxyEnable= xRegistryRootKey->openKey("Settings/ooInetProxyType");
167 if( proxyEnable.is() && 0 != proxyEnable->getLongValue())
168 {
169 // read ftp proxy name
170 css::uno::Reference<css::registry::XRegistryKey> ftpProxy_name = xRegistryRootKey->openKey("Settings/ooInetFTPProxyName");
171 if(ftpProxy_name.is() && !ftpProxy_name->getStringValue().isEmpty()) {
172 OUString ftpHost = "ftp.proxyHost=" + ftpProxy_name->getStringValue();
173
174 // read ftp proxy port
175 css::uno::Reference<css::registry::XRegistryKey> ftpProxy_port = xRegistryRootKey->openKey("Settings/ooInetFTPProxyPort");
176 if(ftpProxy_port.is() && ftpProxy_port->getLongValue()) {
177 OUString ftpPort = "ftp.proxyPort=" + OUString::number(ftpProxy_port->getLongValue());
178
179 pjvm->pushProp(ftpHost);
180 pjvm->pushProp(ftpPort);
181 }
182 }
183
184 // read http proxy name
185 css::uno::Reference<css::registry::XRegistryKey> httpProxy_name = xRegistryRootKey->openKey("Settings/ooInetHTTPProxyName");
186 if(httpProxy_name.is() && !httpProxy_name->getStringValue().isEmpty()) {
187 OUString httpHost = "http.proxyHost=" + httpProxy_name->getStringValue();
188
189 // read http proxy port
190 css::uno::Reference<css::registry::XRegistryKey> httpProxy_port = xRegistryRootKey->openKey("Settings/ooInetHTTPProxyPort");
191 if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
192 OUString httpPort = "http.proxyPort=" + OUString::number(httpProxy_port->getLongValue());
193
194 pjvm->pushProp(httpHost);
195 pjvm->pushProp(httpPort);
196 }
197 }
198
199 // read https proxy name
200 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_name = xRegistryRootKey->openKey("Settings/ooInetHTTPSProxyName");
201 if(httpsProxy_name.is() && !httpsProxy_name->getStringValue().isEmpty()) {
202 OUString httpsHost = "https.proxyHost=" + httpsProxy_name->getStringValue();
203
204 // read https proxy port
205 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_port = xRegistryRootKey->openKey("Settings/ooInetHTTPSProxyPort");
206 if(httpsProxy_port.is() && httpsProxy_port->getLongValue()) {
207 OUString httpsPort = "https.proxyPort=" + OUString::number(httpsProxy_port->getLongValue());
208
209 pjvm->pushProp(httpsHost);
210 pjvm->pushProp(httpsPort);
211 }
212 }
213
214 // read nonProxyHosts
215 css::uno::Reference<css::registry::XRegistryKey> nonProxies_name = xRegistryRootKey->openKey("Settings/ooInetNoProxy");
216 if(nonProxies_name.is() && !nonProxies_name->getStringValue().isEmpty()) {
217 OUString value = nonProxies_name->getStringValue();
218 // replace the separator ";" by "|"
219 value = value.replace(';', '|');
220
221 OUString httpNonProxyHosts = "http.nonProxyHosts=" + value;
222 OUString ftpNonProxyHosts = "ftp.nonProxyHosts=" + value;
223
224 pjvm->pushProp(httpNonProxyHosts);
225 pjvm->pushProp(ftpNonProxyHosts);
226 }
227 }
228 xConfRegistry_simple->close();
229}
230
232void getDefaultLocaleFromConfig(
233 stoc_javavm::JVM * pjvm,
234 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
235 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
236{
237 css::uno::Reference<css::uno::XInterface> xConfRegistry =
238 xSMgr->createInstanceWithContext( "com.sun.star.configuration.ConfigurationRegistry", xCtx );
239 if(!xConfRegistry.is())
240 throw css::uno::RuntimeException(
241 "javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
242
243 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
244 xConfRegistry, css::uno::UNO_QUERY_THROW);
245 xConfRegistry_simple->open("org.openoffice.Setup", true, false);
246 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
247
248 // Since 1.7 Java knows DISPLAY and FORMAT locales, which match our UI and
249 // system locale. See
250 // http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/file/569b1b644416/src/share/classes/java/util/Locale.java
251 // https://docs.oracle.com/javase/tutorial/i18n/locale/scope.html
252 // https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html
253
254 // Read UI language/locale.
255 css::uno::Reference<css::registry::XRegistryKey> xUILocale = xRegistryRootKey->openKey("L10N/ooLocale");
256 if(xUILocale.is() && !xUILocale->getStringValue().isEmpty()) {
257 LanguageTag aLanguageTag( xUILocale->getStringValue());
258 OUString language;
259 OUString script;
260 OUString country;
261 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
262 // Locale.forLanguageTag() are used, or non-standardized variant field
263 // content which we ignore.
264 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
265
266 if(!language.isEmpty()) {
267 OUString prop = "user.language=" + language;
268 pjvm->pushProp(prop);
269 }
270
271 // As of Java 7 also script is supported.
272 if(!script.isEmpty()) {
273 OUString prop = "user.script=" + script;
274 pjvm->pushProp(prop);
275 }
276
277 if(!country.isEmpty()) {
278 OUString prop = "user.country=" + country;
279 pjvm->pushProp(prop);
280 }
281
282 // Java 7 DISPLAY category is our UI language/locale.
283 if(!language.isEmpty()) {
284 OUString prop = "user.language.display=" + language;
285 pjvm->pushProp(prop);
286 }
287
288 if(!script.isEmpty()) {
289 OUString prop = "user.script.display=" + script;
290 pjvm->pushProp(prop);
291 }
292
293 if(!country.isEmpty()) {
294 OUString prop = "user.country.display=" + country;
295 pjvm->pushProp(prop);
296 }
297 }
298
299 // Read system locale.
300 css::uno::Reference<css::registry::XRegistryKey> xLocale = xRegistryRootKey->openKey("L10N/ooSetupSystemLocale");
301 if(xLocale.is() && !xLocale->getStringValue().isEmpty()) {
302 LanguageTag aLanguageTag( xLocale->getStringValue());
303 OUString language;
304 OUString script;
305 OUString country;
306 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
307 // Locale.forLanguageTag() are used, or non-standardized variant field
308 // content which we ignore.
309 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
310
311 // Java 7 FORMAT category is our system locale.
312 if(!language.isEmpty()) {
313 OUString prop = "user.language.format=" + language;
314 pjvm->pushProp(prop);
315 }
316
317 if(!script.isEmpty()) {
318 OUString prop = "user.script.format=" + script;
319 pjvm->pushProp(prop);
320 }
321
322 if(!country.isEmpty()) {
323 OUString prop = "user.country.format=" + country;
324 pjvm->pushProp(prop);
325 }
326 }
327
328 xConfRegistry_simple->close();
329}
330
332void getJavaPropsFromSafetySettings(
333 stoc_javavm::JVM * pjvm,
334 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
335 const css::uno::Reference<css::uno::XComponentContext> &xCtx)
336{
337 css::uno::Reference<css::uno::XInterface> xConfRegistry =
338 xSMgr->createInstanceWithContext(
339 "com.sun.star.configuration.ConfigurationRegistry",
340 xCtx);
341 if(!xConfRegistry.is())
342 throw css::uno::RuntimeException(
343 "javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
344
345 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
346 xConfRegistry, css::uno::UNO_QUERY_THROW);
347 xConfRegistry_simple->open(
348 "org.openoffice.Office.Java",
349 true, false);
350 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey =
351 xConfRegistry_simple->getRootKey();
352
353 if (xRegistryRootKey.is())
354 {
355 css::uno::Reference<css::registry::XRegistryKey> key_NetAccess= xRegistryRootKey->openKey("VirtualMachine/NetAccess");
356 if (key_NetAccess.is())
357 {
358 sal_Int32 val= key_NetAccess->getLongValue();
359 OUString sVal;
360 switch( val)
361 {
362 case 0: sVal = "host";
363 break;
364 case 1: sVal = "unrestricted";
365 break;
366 case 3: sVal = "none";
367 break;
368 }
369 OUString sProperty = "appletviewer.security.mode=" + sVal;
370 pjvm->pushProp(sProperty);
371 }
372 css::uno::Reference<css::registry::XRegistryKey> key_CheckSecurity= xRegistryRootKey->openKey(
373 "VirtualMachine/Security");
374 if( key_CheckSecurity.is())
375 {
376 bool val = static_cast<bool>(key_CheckSecurity->getLongValue());
377 OUString sProperty("stardiv.security.disableSecurity=");
378 if( val)
379 sProperty += "false";
380 else
381 sProperty += "true";
382 pjvm->pushProp( sProperty);
383 }
384 }
385 xConfRegistry_simple->close();
386}
387
388void setTimeZone(stoc_javavm::JVM * pjvm) noexcept {
389 /* A Bug in the Java function
390 ** struct Hjava_util_Properties * java_lang_System_initProperties(
391 ** struct Hjava_lang_System *this,
392 ** struct Hjava_util_Properties *props);
393 ** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
394 */
395 struct tm *tmData;
396 time_t clock = time(nullptr);
397 tzset();
398 tmData = localtime(&clock);
399#ifdef MACOSX
400 char * p = tmData->tm_zone;
401#elif defined(_MSC_VER)
402 char * p = _tzname[0];
403 (void)tmData;
404#else
405 char * p = tzname[0];
406 (void)tmData;
407#endif
408
409 if (!strcmp(TIMEZONE, p))
410 pjvm->pushProp("user.timezone=ECT");
411}
412
414void initVMConfiguration(
415 stoc_javavm::JVM * pjvm,
416 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
417 const css::uno::Reference<css::uno::XComponentContext > &xCtx)
418{
420 try {
421 getINetPropsFromConfig(&jvm, xSMgr, xCtx);
422 }
423 catch(const css::uno::Exception & exception) {
424 SAL_INFO("stoc", "can not get INETProps because of " << exception);
425 }
426
427 try {
428 getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
429 }
430 catch(const css::uno::Exception & exception) {
431 SAL_INFO("stoc", "can not get locale because of " << exception);
432 }
433
434 try
435 {
436 getJavaPropsFromSafetySettings(&jvm, xSMgr, xCtx);
437 }
438 catch(const css::uno::Exception & exception) {
439 SAL_INFO("stoc", "couldn't get safety settings because of " << exception);
440 }
441
442 *pjvm= jvm;
443
444 // rhbz#1285356, native look will be gtk2, which crashes
445 // when gtk3 is already loaded. Until there is a solution
446 // java-side force look and feel to something that doesn't
447 // crash when we are using gtk3
448 if (getenv("STOC_FORCE_SYSTEM_LAF"))
449 pjvm->pushProp("swing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel");
450
451 setTimeZone(pjvm);
452}
453
454class DetachCurrentThread {
455public:
456 explicit DetachCurrentThread(JavaVM * jvm): m_jvm(jvm) {}
457
458 ~DetachCurrentThread() {
459 if (m_jvm->DetachCurrentThread() != 0) {
460 OSL_ASSERT(false);
461 }
462 }
463
464 DetachCurrentThread(const DetachCurrentThread&) = delete;
465 DetachCurrentThread& operator=(const DetachCurrentThread&) = delete;
466
467private:
468 JavaVM * m_jvm;
469};
470
471}
472
473JavaVirtualMachine::JavaVirtualMachine(
474 css::uno::Reference< css::uno::XComponentContext > xContext):
475 WeakComponentImplHelper(m_aMutex),
476 m_xContext(std::move(xContext)),
477 m_bDisposed(false),
478 m_pJavaVm(nullptr),
479 m_aAttachGuards(destroyAttachGuards) // TODO check for validity
480{}
481
482void SAL_CALL
483JavaVirtualMachine::initialize(css::uno::Sequence< css::uno::Any > const &
484 rArguments)
485{
486 osl::MutexGuard aGuard(m_aMutex);
487 if (m_bDisposed)
488 throw css::lang::DisposedException(
489 "", getXWeak());
490 if (m_xUnoVirtualMachine.is())
491 throw css::uno::RuntimeException(
492 "bad call to initialize",
493 getXWeak());
494 css::beans::NamedValue val;
495 if (rArguments.getLength() == 1 && (rArguments[0] >>= val) && val.Name == "UnoVirtualMachine" )
496 {
497 OSL_ENSURE(
498 sizeof (sal_Int64) >= sizeof (jvmaccess::UnoVirtualMachine *),
499 "Pointer cannot be represented as sal_Int64");
500 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
501 static_cast< jvmaccess::UnoVirtualMachine * >(nullptr));
502 val.Value >>= nPointer;
504 reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer);
505 } else {
506 OSL_ENSURE(
507 sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *),
508 "Pointer cannot be represented as sal_Int64");
509 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
510 static_cast< jvmaccess::VirtualMachine * >(nullptr));
511 if (rArguments.getLength() == 1)
512 rArguments[0] >>= nPointer;
514 reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer));
515 if (vm.is()) {
516 try {
519 css::uno::Any anyEx = cppu::getCaughtException();
520 throw css::lang::WrappedTargetRuntimeException(
521 "jvmaccess::UnoVirtualMachine::CreationException",
522 getXWeak(), anyEx );
523 }
524 }
525 }
526 if (!m_xUnoVirtualMachine.is()) {
527 throw css::lang::IllegalArgumentException(
528 "sequence of exactly one any containing either (a) a"
529 " com.sun.star.beans.NamedValue with Name"
530 " \"UnoVirtualMachine\" and Value a hyper representing a"
531 " non-null pointer to a jvmaccess:UnoVirtualMachine, or (b)"
532 " a hyper representing a non-null pointer to a"
533 " jvmaccess::VirtualMachine required",
534 getXWeak(), 0);
535 }
536 m_xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
537}
538
540{
541 return "com.sun.star.comp.stoc.JavaVirtualMachine";
542}
543
544sal_Bool SAL_CALL
545JavaVirtualMachine::supportsService(OUString const & rServiceName)
546{
547 return cppu::supportsService(this, rServiceName);
548}
549
550css::uno::Sequence< OUString > SAL_CALL
552{
553 return { "com.sun.star.java.JavaVirtualMachine" };
554}
555
556css::uno::Any SAL_CALL
557JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
558{
559 osl::MutexGuard aGuard(m_aMutex);
560 if (m_bDisposed)
561 throw css::lang::DisposedException(
562 "", getXWeak());
563 css::uno::Sequence< sal_Int8 > aId(16);
564 rtl_getGlobalProcessId(reinterpret_cast< sal_uInt8 * >(aId.getArray()));
565 enum ReturnType {
566 RETURN_JAVAVM, RETURN_VIRTUALMACHINE, RETURN_UNOVIRTUALMACHINE };
567 ReturnType returnType =
568 rProcessId.getLength() == 17 && rProcessId[16] == 0
569 ? RETURN_VIRTUALMACHINE
570 : rProcessId.getLength() == 17 && rProcessId[16] == 1
571 ? RETURN_UNOVIRTUALMACHINE
572 : RETURN_JAVAVM;
573 css::uno::Sequence< sal_Int8 > aProcessId(rProcessId);
574 if (returnType != RETURN_JAVAVM)
575 aProcessId.realloc(16);
576 if (aId != aProcessId)
577 return css::uno::Any();
578
579 std::unique_ptr<JavaInfo> info;
580 while (!m_xVirtualMachine.is()) // retry until successful
581 {
582 stoc_javavm::JVM aJvm;
583 initVMConfiguration(&aJvm, m_xContext->getServiceManager(),
584 m_xContext);
585 const std::vector<OUString> & props = aJvm.getProperties();
586 std::vector<OUString> options;
587 options.reserve(props.size());
588 for (auto const& i : props)
589 {
590 options.push_back(i.startsWith("-") ? i : "-D" + i);
591 }
592
593 JNIEnv * pMainThreadEnv = nullptr;
595
596 if (getenv("STOC_FORCE_NO_JRE"))
597 errcode = JFW_E_NO_SELECT;
598 else
599 errcode = jfw_startVM(info.get(), options, & m_pJavaVm,
600 & pMainThreadEnv);
601
602 bool bStarted = false;
603 switch (errcode)
604 {
605 case JFW_E_NONE: bStarted = true; break;
606 case JFW_E_NO_SELECT:
607 {
608 // No Java configured. We silently run the Java configuration
609 info.reset();
611 if (getenv("STOC_FORCE_NO_JRE"))
612 errFind = JFW_E_NO_JAVA_FOUND;
613 if (errFind == JFW_E_NONE)
614 {
615 continue;
616 }
617 else if (errFind == JFW_E_NO_JAVA_FOUND)
618 {
619
620 //Warning MessageBox:
621 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task.
622 //Please install a JRE and restart %PRODUCTNAME.
623 css::java::JavaNotFoundException exc(
624 "JavaVirtualMachine::getJavaVM failed because"
625 " No suitable JRE found!",
626 getXWeak());
627 askForRetry(css::uno::Any(exc));
628 return css::uno::Any();
629 }
630 else
631 {
632 //An unexpected error occurred
633 throw css::uno::RuntimeException(
634 "[JavaVirtualMachine]:An unexpected error occurred"
635 " while searching for a Java, " + OUString::number(errFind), nullptr);
636 }
637 }
639 {
640 //Warning MessageBox:
641 // The %PRODUCTNAME configuration has been changed. Under Tools
642 // - Options - %PRODUCTNAME - Java, select the Java runtime environment
643 // you want to have used by %PRODUCTNAME.
644 css::java::InvalidJavaSettingsException exc(
645 "JavaVirtualMachine::getJavaVM failed because"
646 " Java settings have changed!",
647 getXWeak());
648 askForRetry(css::uno::Any(exc));
649 return css::uno::Any();
650 }
652 {
653 if (comphelper::IsContextFlagActive("DontEnableJava"))
654 return css::uno::Any();
655
656 //QueryBox:
657 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform
658 //this task. However, use of a JRE has been disabled. Do you want to
659 //enable the use of a JRE now?
660 css::java::JavaDisabledException exc(
661 "JavaVirtualMachine::getJavaVM failed because Java is disabled!",
662 getXWeak());
663 if( ! askForRetry(css::uno::Any(exc)))
664 return css::uno::Any();
665 continue;
666 }
668 {
669 //If the creation failed because the JRE has been uninstalled then
670 //we search another one. As long as there is a javaldx, we should
671 //never come into this situation. javaldx checks always if the JRE
672 //still exist.
673 std::unique_ptr<JavaInfo> aJavaInfo;
674 if (JFW_E_NONE == jfw_getSelectedJRE(&aJavaInfo))
675 {
676 bool bExist = false;
677 if (JFW_E_NONE == jfw_existJRE(aJavaInfo.get(), &bExist))
678 {
679 if (!bExist
680 && ! (aJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
681 {
682 info.reset();
684 &info);
685 if (errFind == JFW_E_NONE)
686 {
687 continue;
688 }
689 }
690 }
691 }
692
693 //Error: %PRODUCTNAME requires a Java
694 //runtime environment (JRE) to perform this task. The selected JRE
695 //is defective. Please select another version or install a new JRE
696 //and select it under Tools - Options - %PRODUCTNAME - Java.
697 css::java::JavaVMCreationFailureException exc(
698 "JavaVirtualMachine::getJavaVM failed because Java is defective!",
699 getXWeak(), 0);
700 askForRetry(css::uno::Any(exc));
701 return css::uno::Any();
702 }
704 {
705 //This service should make sure that we do not start java twice.
706 OSL_ASSERT(false);
707 break;
708 }
710 {
711 //Error:
712 //For the selected Java runtime environment to work properly,
713 //%PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.
714 css::java::RestartRequiredException exc(
715 "JavaVirtualMachine::getJavaVM failed because "
716 "Office must be restarted before Java can be used!",
717 getXWeak());
718 askForRetry(css::uno::Any(exc));
719 return css::uno::Any();
720 }
721 default:
722 //RuntimeException: error is somewhere in the java framework.
723 //An unexpected error occurred
724 throw css::uno::RuntimeException(
725 "[JavaVirtualMachine]:An unexpected error occurred"
726 " while starting Java!", nullptr);
727 }
728
729 if (bStarted)
730 {
731 {
732 DetachCurrentThread detach(m_pJavaVm);
733 // necessary to make debugging work; this thread will be
734 // suspended when the destructor of detach returns
736 m_pJavaVm, JNI_VERSION_1_2, true, pMainThreadEnv);
737 setUpUnoVirtualMachine(pMainThreadEnv);
738 }
739 // Listen for changes in the configuration (e.g. proxy settings):
740 // TODO this is done too late; changes to the configuration done
741 // after the above call to initVMConfiguration are lost
743
744 break;
745 }
746 }
747 if (!m_xUnoVirtualMachine.is()) {
748 try {
752 css::uno::Any anyEx = cppu::getCaughtException();
753 throw css::lang::WrappedTargetRuntimeException(
754 "jvmaccess::VirtualMachine::AttachGuard::CreationException occurred",
755 getXWeak(), anyEx );
756 }
757 }
758 switch (returnType) {
759 default: // RETURN_JAVAVM
760 if (m_pJavaVm == nullptr) {
761 throw css::uno::RuntimeException(
762 "JavaVirtualMachine service was initialized in a way"
763 " that the requested JavaVM pointer is not available",
764 getXWeak());
765 }
766 return css::uno::Any(reinterpret_cast< sal_IntPtr >(m_pJavaVm));
767 case RETURN_VIRTUALMACHINE:
768 OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
769 return css::uno::Any(
770 reinterpret_cast< sal_Int64 >(
771 m_xUnoVirtualMachine->getVirtualMachine().get()));
772 case RETURN_UNOVIRTUALMACHINE:
773 OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
774 return css::uno::Any(
775 reinterpret_cast< sal_Int64 >(m_xUnoVirtualMachine.get()));
776 }
777}
778
780{
781 osl::MutexGuard aGuard(m_aMutex);
782 if (m_bDisposed)
783 throw css::lang::DisposedException(
784 OUString(), getXWeak());
785 return m_xUnoVirtualMachine.is();
786}
787
789{
790 {
791 osl::MutexGuard aGuard(m_aMutex);
792 if (m_bDisposed)
793 throw css::lang::DisposedException(
794 OUString(), getXWeak());
795 }
796// stoc_javavm::JVM aJvm;
797// initVMConfiguration(&aJvm, m_xContext->getServiceManager(), m_xContext);
798// return aJvm.isEnabled();
799 //ToDo
800 bool bEnabled = false;
801 if (jfw_getEnabled( & bEnabled) != JFW_E_NONE)
802 throw css::uno::RuntimeException();
803 return bEnabled;
804}
805
807{
808 osl::MutexGuard aGuard(m_aMutex);
809 if (m_bDisposed)
810 throw css::lang::DisposedException(
811 OUString(), getXWeak());
812 // TODO isThreadAttached only returns true if the thread was attached via
813 // registerThread:
814 GuardStack * pStack
815 = static_cast< GuardStack * >(m_aAttachGuards.getData());
816 return pStack != nullptr && !pStack->empty();
817}
818
820{
821 osl::MutexGuard aGuard(m_aMutex);
822 if (m_bDisposed)
823 throw css::lang::DisposedException(
824 "", getXWeak());
825 if (!m_xUnoVirtualMachine.is())
826 throw css::uno::RuntimeException(
827 "JavaVirtualMachine::registerThread: null VirtualMachine",
828 getXWeak());
829 GuardStack * pStack
830 = static_cast< GuardStack * >(m_aAttachGuards.getData());
831 if (pStack == nullptr)
832 {
833 pStack = new GuardStack;
834 m_aAttachGuards.setData(pStack);
835 }
836 try
837 {
838 pStack->push(
840 m_xUnoVirtualMachine->getVirtualMachine()));
841 }
843 {
844 css::uno::Any anyEx = cppu::getCaughtException();
845 throw css::lang::WrappedTargetRuntimeException(
846 "JavaVirtualMachine::registerThread: jvmaccess::"
847 "VirtualMachine::AttachGuard::CreationException",
848 getXWeak(), anyEx );
849 }
850}
851
853{
854 osl::MutexGuard aGuard(m_aMutex);
855 if (m_bDisposed)
856 throw css::lang::DisposedException(
857 "", getXWeak());
858 if (!m_xUnoVirtualMachine.is())
859 throw css::uno::RuntimeException(
860 "JavaVirtualMachine::revokeThread: null VirtualMachine",
861 getXWeak());
862 GuardStack * pStack
863 = static_cast< GuardStack * >(m_aAttachGuards.getData());
864 if (pStack == nullptr || pStack->empty())
865 throw css::uno::RuntimeException(
866 "JavaVirtualMachine::revokeThread: no matching registerThread",
867 getXWeak());
868 delete pStack->top();
869 pStack->pop();
870}
871
872void SAL_CALL
873JavaVirtualMachine::disposing(css::lang::EventObject const & rSource)
874{
875 osl::MutexGuard aGuard(m_aMutex);
876 if (rSource.Source == m_xInetConfiguration)
877 m_xInetConfiguration.clear();
878 if (rSource.Source == m_xJavaConfiguration)
879 m_xJavaConfiguration.clear();
880}
881
883 css::container::ContainerEvent const &)
884{}
885
887 css::container::ContainerEvent const &)
888{}
889
890// If a user changes the setting, for example for proxy settings, then this
891// function will be called from the configuration manager. Even if the .xml
892// file does not contain an entry yet and that entry has to be inserted, this
893// function will be called. We call java.lang.System.setProperty for the new
894// values.
896 css::container::ContainerEvent const & rEvent)
897{
898 // TODO Using the new value stored in rEvent is wrong here. If two threads
899 // receive different elementReplaced calls in quick succession, it is
900 // unspecified which changes the JVM's system properties last. A correct
901 // solution must atomically (i.e., protected by a mutex) read the latest
902 // value from the configuration and set it as a system property at the JVM.
903
904 OUString aAccessor;
905 rEvent.Accessor >>= aAccessor;
906 OUString aPropertyName;
907 OUString aPropertyName2;
908 OUString aPropertyValue;
909 bool bSecurityChanged = false;
910 if ( aAccessor == "ooInetProxyType" )
911 {
912 // Proxy none, manually
913 sal_Int32 value = 0;
914 rEvent.Element >>= value;
916 return;
917 }
918 else if ( aAccessor == "ooInetHTTPProxyName" )
919 {
920 aPropertyName = "http.proxyHost";
921 rEvent.Element >>= aPropertyValue;
922 }
923 else if ( aAccessor == "ooInetHTTPProxyPort" )
924 {
925 aPropertyName = "http.proxyPort";
926 sal_Int32 n = 0;
927 rEvent.Element >>= n;
928 aPropertyValue = OUString::number(n);
929 }
930 else if ( aAccessor == "ooInetHTTPSProxyName" )
931 {
932 aPropertyName = "https.proxyHost";
933 rEvent.Element >>= aPropertyValue;
934 }
935 else if ( aAccessor == "ooInetHTTPSProxyPort" )
936 {
937 aPropertyName = "https.proxyPort";
938 sal_Int32 n = 0;
939 rEvent.Element >>= n;
940 aPropertyValue = OUString::number(n);
941 }
942 else if ( aAccessor == "ooInetFTPProxyName" )
943 {
944 aPropertyName = "ftp.proxyHost";
945 rEvent.Element >>= aPropertyValue;
946 }
947 else if ( aAccessor == "ooInetFTPProxyPort" )
948 {
949 aPropertyName = "ftp.proxyPort";
950 sal_Int32 n = 0;
951 rEvent.Element >>= n;
952 aPropertyValue = OUString::number(n);
953 }
954 else if ( aAccessor == "ooInetNoProxy" )
955 {
956 aPropertyName = "http.nonProxyHosts";
957 aPropertyName2 = "ftp.nonProxyHosts";
958 rEvent.Element >>= aPropertyValue;
959 aPropertyValue = aPropertyValue.replace(';', '|');
960 }
961 else if ( aAccessor == "NetAccess" )
962 {
963 aPropertyName = "appletviewer.security.mode";
964 sal_Int32 n = 0;
965 if (rEvent.Element >>= n)
966 switch (n)
967 {
968 case 0:
969 aPropertyValue = "host";
970 break;
971 case 1:
972 aPropertyValue = "unrestricted";
973 break;
974 case 3:
975 aPropertyValue = "none";
976 break;
977 }
978 else
979 return;
980 bSecurityChanged = true;
981 }
982 else if ( aAccessor == "Security" )
983 {
984 aPropertyName = "stardiv.security.disableSecurity";
985 bool b;
986 if (rEvent.Element >>= b)
987 if (b)
988 aPropertyValue = "false";
989 else
990 aPropertyValue = "true";
991 else
992 return;
993 bSecurityChanged = true;
994 }
995 else
996 return;
997
999 {
1000 osl::MutexGuard aGuard(m_aMutex);
1001 if (m_xUnoVirtualMachine.is()) {
1002 xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
1003 }
1004 }
1005 if (!xVirtualMachine.is())
1006 return;
1007
1008 try
1009 {
1011 xVirtualMachine);
1012 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1013
1014 // call java.lang.System.setProperty
1015 // String setProperty( String key, String value)
1016 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1017 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/lang/System", nullptr);
1018 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1019 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.setProperty", nullptr);
1020
1021 jstring jsPropName= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName.getStr()), aPropertyName.getLength());
1022 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1023
1024 // remove the property if it does not have a value ( user left the dialog field empty)
1025 // or if the port is set to 0
1026 aPropertyValue= aPropertyValue.trim();
1027 if( aPropertyValue.isEmpty() ||
1028 ( ( aPropertyName == "ftp.proxyPort" || aPropertyName == "http.proxyPort" /*|| aPropertyName == "socksProxyPort"*/ ) && aPropertyValue == "0" )
1029 )
1030 {
1031 // call java.lang.System.getProperties
1032 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1033 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getProperties", nullptr);
1034 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1035 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.getProperties", nullptr);
1036 // call java.util.Properties.remove
1037 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1038 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/util/Properties", nullptr);
1039 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1040 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.util.Properties.remove", nullptr);
1041 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName);
1042
1043 // special case for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1044 // has a value for two java properties
1045 if (!aPropertyName2.isEmpty())
1046 {
1047 jstring jsPropName2= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName2.getStr()), aPropertyName2.getLength());
1048 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1049 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName2);
1050 }
1051 }
1052 else
1053 {
1054 // Change the Value of the property
1055 jstring jsPropValue= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyValue.getStr()), aPropertyValue.getLength());
1056 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1057 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName, jsPropValue);
1058 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1059
1060 // special case for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1061 // has a value for two java properties
1062 if (!aPropertyName2.isEmpty())
1063 {
1064 jstring jsPropName2= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName2.getStr()), aPropertyName2.getLength());
1065 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1066 jsPropValue= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyValue.getStr()), aPropertyValue.getLength());
1067 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1068 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName2, jsPropValue);
1069 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1070 }
1071 }
1072
1073 // If the settings for Security and NetAccess changed then we have to notify the SandboxSecurity
1074 // SecurityManager
1075 // call System.getSecurityManager()
1076 if (bSecurityChanged)
1077 {
1078 jmethodID jmGetSecur= pJNIEnv->GetStaticMethodID( jcSystem,"getSecurityManager","()Ljava/lang/SecurityManager;");
1079 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getSecurityManager", nullptr);
1080 jobject joSecur= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetSecur);
1081 if (joSecur != nullptr)
1082 {
1083 // Make sure the SecurityManager is our SandboxSecurity
1084 // FindClass("com.sun.star.lib.sandbox.SandboxSecurityManager" only worked at the first time
1085 // this code was executed. Maybe it is a security feature. However, all attempts to debug the
1086 // SandboxSecurity class (maybe the VM invokes checkPackageAccess) failed.
1087// jclass jcSandboxSec= pJNIEnv->FindClass("com.sun.star.lib.sandbox.SandboxSecurity");
1088// if(pJNIEnv->ExceptionOccurred()) throw RuntimeException("JNI:FindClass com.sun.star.lib.sandbox.SandboxSecurity");
1089// jboolean bIsSand= pJNIEnv->IsInstanceOf( joSecur, jcSandboxSec);
1090 // The SecurityManagers class Name must be com.sun.star.lib.sandbox.SandboxSecurity
1091 jclass jcSec= pJNIEnv->GetObjectClass( joSecur);
1092 jclass jcClass= pJNIEnv->FindClass("java/lang/Class");
1093 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java.lang.Class", nullptr);
1094 jmethodID jmName= pJNIEnv->GetMethodID( jcClass,"getName","()Ljava/lang/String;");
1095 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.lang.Class.getName", nullptr);
1096 jstring jsClass= static_cast<jstring>(pJNIEnv->CallObjectMethod( jcSec, jmName));
1097 const jchar* jcharName= pJNIEnv->GetStringChars( jsClass, nullptr);
1098 OUString sName(reinterpret_cast<sal_Unicode const *>(jcharName));
1099 bool bIsSandbox;
1100 bIsSandbox = sName == "com.sun.star.lib.sandbox.SandboxSecurity";
1101 pJNIEnv->ReleaseStringChars( jsClass, jcharName);
1102
1103 if (bIsSandbox)
1104 {
1105 // call SandboxSecurity.reset
1106 jmethodID jmReset= pJNIEnv->GetMethodID( jcSec,"reset","()V");
1107 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID com.sun.star.lib.sandbox.SandboxSecurity.reset", nullptr);
1108 pJNIEnv->CallVoidMethod( joSecur, jmReset);
1109 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallVoidMethod com.sun.star.lib.sandbox.SandboxSecurity.reset", nullptr);
1110 }
1111 }
1112 }
1113 }
1115 {
1116 css::uno::Any anyEx = cppu::getCaughtException();
1117 throw css::lang::WrappedTargetRuntimeException(
1118 "jvmaccess::VirtualMachine::AttachGuard::CreationException",
1119 getXWeak(), anyEx );
1120 }
1121}
1122
1124{
1125 if (m_xInetConfiguration.is())
1126 // We should never get here, but just in case...
1127 try
1128 {
1129 m_xInetConfiguration->removeContainerListener(this);
1130 }
1131 catch (css::uno::Exception &)
1132 {
1133 OSL_FAIL("com.sun.star.uno.Exception caught");
1134 }
1135 if (m_xJavaConfiguration.is())
1136 // We should never get here, but just in case...
1137 try
1138 {
1139 m_xJavaConfiguration->removeContainerListener(this);
1140 }
1141 catch (css::uno::Exception &)
1142 {
1143 OSL_FAIL("com.sun.star.uno.Exception caught");
1144 }
1145}
1146
1148{
1149 css::uno::Reference< css::container::XContainer > xContainer1;
1150 css::uno::Reference< css::container::XContainer > xContainer2;
1151 {
1152 osl::MutexGuard aGuard(m_aMutex);
1153 m_bDisposed = true;
1154 xContainer1 = m_xInetConfiguration;
1155 m_xInetConfiguration.clear();
1156 xContainer2 = m_xJavaConfiguration;
1157 m_xJavaConfiguration.clear();
1158 }
1159 if (xContainer1.is())
1160 xContainer1->removeContainerListener(this);
1161 if (xContainer2.is())
1162 xContainer2->removeContainerListener(this);
1163}
1164
1165/*We listen to changes in the configuration. For example, the user changes the proxy
1166 settings in the options dialog (menu tools). Then we are notified of this change and
1167 if the java vm is already running we change the properties (System.lang.System.setProperties)
1168 through JNI.
1169 To receive notifications this class implements XContainerListener.
1170*/
1172{
1173 try
1174 {
1175 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
1176 m_xContext->getValueByName(
1177 "/singletons/com.sun.star.configuration.theDefaultProvider"),
1178 css::uno::UNO_QUERY);
1179
1180 if (xConfigProvider.is())
1181 {
1182 // We register this instance as listener to changes in org.openoffice.Inet/Settings
1183 // arguments for ConfigurationAccess
1184 css::uno::Sequence<css::uno::Any> aArguments(comphelper::InitAnyPropertySequence(
1185 {
1186 {"nodepath", css::uno::Any(OUString("org.openoffice.Inet/Settings"))},
1187 {"depth", css::uno::Any(sal_Int32(-1))}
1188 }));
1190 xConfigProvider->createInstanceWithArguments(
1191 "com.sun.star.configuration.ConfigurationAccess",
1192 aArguments),
1193 css::uno::UNO_QUERY);
1194
1195 if (m_xInetConfiguration.is())
1196 m_xInetConfiguration->addContainerListener(this);
1197
1198 // now register as listener to changes in org.openoffice.Java/VirtualMachine
1199 css::uno::Sequence<css::uno::Any> aArguments2(comphelper::InitAnyPropertySequence(
1200 {
1201 {"nodepath", css::uno::Any(OUString("org.openoffice.Office.Java/VirtualMachine"))},
1202 {"depth", css::uno::Any(sal_Int32(-1))} // depth: -1 means unlimited
1203 }));
1205 xConfigProvider->createInstanceWithArguments(
1206 "com.sun.star.configuration.ConfigurationAccess",
1207 aArguments2),
1208 css::uno::UNO_QUERY);
1209
1210 if (m_xJavaConfiguration.is())
1211 m_xJavaConfiguration->addContainerListener(this);
1212 }
1213 }catch(const css::uno::Exception & e)
1214 {
1215 SAL_INFO("stoc", "could not set up listener for Configuration because of >" << e << "<");
1216 }
1217}
1218
1219// param true: all Inet setting are set as Java Properties on a live VM.
1220// false: the Java net properties are set to empty value.
1222{
1223 osl::MutexGuard aGuard(m_aMutex);
1224 try
1225 {
1226 if (m_xUnoVirtualMachine.is())
1227 {
1229 m_xUnoVirtualMachine->getVirtualMachine());
1230 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1231
1232 // The Java Properties
1233 OUString sFtpProxyHost("ftp.proxyHost");
1234 OUString sFtpProxyPort("ftp.proxyPort");
1235 OUString sFtpNonProxyHosts ("ftp.nonProxyHosts");
1236 OUString sHttpProxyHost("http.proxyHost");
1237 OUString sHttpProxyPort("http.proxyPort");
1238 OUString sHttpNonProxyHosts("http.nonProxyHosts");
1239
1240 // create Java Properties as JNI strings
1241 jstring jsFtpProxyHost= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpProxyHost.getStr()), sFtpProxyHost.getLength());
1242 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1243 jstring jsFtpProxyPort= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpProxyPort.getStr()), sFtpProxyPort.getLength());
1244 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1245 jstring jsFtpNonProxyHosts= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpNonProxyHosts.getStr()), sFtpNonProxyHosts.getLength());
1246 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1247 jstring jsHttpProxyHost= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyHost.getStr()), sHttpProxyHost.getLength());
1248 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1249 jstring jsHttpProxyPort= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyPort.getStr()), sHttpProxyPort.getLength());
1250 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1251 jstring jsHttpNonProxyHosts= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpNonProxyHosts.getStr()), sHttpNonProxyHosts.getLength());
1252 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1253
1254 // prepare java.lang.System.setProperty
1255 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1256 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/lang/System", nullptr);
1257 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1258 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.setProperty", nullptr);
1259
1260 // call java.lang.System.getProperties
1261 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1262 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getProperties", nullptr);
1263 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1264 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.getProperties", nullptr);
1265 // prepare java.util.Properties.remove
1266 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1267 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/util/Properties", nullptr);
1268
1269 if (set_reset)
1270 {
1271 // Set all network properties with the VM
1272 JVM jvm;
1273 getINetPropsFromConfig( &jvm, m_xContext->getServiceManager(), m_xContext);
1274 const ::std::vector< OUString> & Props = jvm.getProperties();
1275
1276 for( auto& prop : Props)
1277 {
1278 sal_Int32 index= prop.indexOf( '=');
1279 std::u16string_view propName= prop.subView( 0, index);
1280 OUString propValue= prop.copy( index + 1);
1281
1282 if( propName == sFtpProxyHost)
1283 {
1284 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1285 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1286 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyHost, jsVal);
1287 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1288 }
1289 else if( propName == sFtpProxyPort)
1290 {
1291 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1292 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1293 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyPort, jsVal);
1294 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1295 }
1296 else if( propName == sFtpNonProxyHosts)
1297 {
1298 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1299 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1300 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpNonProxyHosts, jsVal);
1301 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1302 }
1303 else if( propName == sHttpProxyHost)
1304 {
1305 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1306 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1307 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyHost, jsVal);
1308 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1309 }
1310 else if( propName == sHttpProxyPort)
1311 {
1312 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1313 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1314 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyPort, jsVal);
1315 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1316 }
1317 else if( propName == sHttpNonProxyHosts)
1318 {
1319 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1320 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1321 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpNonProxyHosts, jsVal);
1322 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1323 }
1324 }
1325 }
1326 else
1327 {
1328 // call java.util.Properties.remove
1329 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1330 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.util.Property.remove", nullptr);
1331 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyHost);
1332 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyPort);
1333 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpNonProxyHosts);
1334 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyHost);
1335 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyPort);
1336 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpNonProxyHosts);
1337 }
1338 }
1339 }
1340 catch (css::uno::RuntimeException &)
1341 {
1342 OSL_FAIL("RuntimeException");
1343 }
1345 {
1346 OSL_FAIL("jvmaccess::VirtualMachine::AttachGuard::CreationException");
1347 }
1348}
1349
1351 css::uno::Reference< css::util::XMacroExpander > exp = css::util::theMacroExpander::get(m_xContext);
1352 OUString baseUrl;
1353 try {
1354 baseUrl = exp->expandMacros("$URE_INTERNAL_JAVA_DIR/");
1355 } catch (css::lang::IllegalArgumentException &) {
1356 css::uno::Any anyEx = cppu::getCaughtException();
1357 throw css::lang::WrappedTargetRuntimeException(
1358 "css::lang::IllegalArgumentException",
1359 getXWeak(), anyEx );
1360 }
1361 OUString classPath;
1362 try {
1363 classPath = exp->expandMacros("$URE_INTERNAL_JAVA_CLASSPATH");
1364 } catch (css::lang::IllegalArgumentException &) {}
1365 jclass class_URLClassLoader = environment->FindClass(
1366 "java/net/URLClassLoader");
1367 if (class_URLClassLoader == nullptr) {
1368 handleJniException(environment);
1369 }
1370 jmethodID ctor_URLClassLoader = environment->GetMethodID(
1371 class_URLClassLoader, "<init>", "([Ljava/net/URL;)V");
1372 if (ctor_URLClassLoader == nullptr) {
1373 handleJniException(environment);
1374 }
1375 jclass class_URL = environment->FindClass("java/net/URL");
1376 if (class_URL == nullptr) {
1377 handleJniException(environment);
1378 }
1379 jmethodID ctor_URL_1 = environment->GetMethodID(
1380 class_URL, "<init>", "(Ljava/lang/String;)V");
1381 if (ctor_URL_1 == nullptr) {
1382 handleJniException(environment);
1383 }
1384 jvalue args[3];
1385 args[0].l = environment->NewString(
1386 reinterpret_cast< jchar const * >(baseUrl.getStr()),
1387 static_cast< jsize >(baseUrl.getLength()));
1388 if (args[0].l == nullptr) {
1389 handleJniException(environment);
1390 }
1391 jobject base = environment->NewObjectA(class_URL, ctor_URL_1, args);
1392 if (base == nullptr) {
1393 handleJniException(environment);
1394 }
1395 jmethodID ctor_URL_2 = environment->GetMethodID(
1396 class_URL, "<init>", "(Ljava/net/URL;Ljava/lang/String;)V");
1397 if (ctor_URL_2 == nullptr) {
1398 handleJniException(environment);
1399 }
1400 jobjectArray classpath = jvmaccess::ClassPath::translateToUrls(
1401 m_xContext, environment, classPath);
1402 if (classpath == nullptr) {
1403 handleJniException(environment);
1404 }
1405 args[0].l = base;
1406 args[1].l = environment->NewStringUTF("unoloader.jar");
1407 if (args[1].l == nullptr) {
1408 handleJniException(environment);
1409 }
1410 args[0].l = environment->NewObjectA(class_URL, ctor_URL_2, args);
1411 if (args[0].l == nullptr) {
1412 handleJniException(environment);
1413 }
1414 args[0].l = environment->NewObjectArray(1, class_URL, args[0].l);
1415 if (args[0].l == nullptr) {
1416 handleJniException(environment);
1417 }
1418 jobject cl1 = environment->NewObjectA(
1419 class_URLClassLoader, ctor_URLClassLoader, args);
1420 if (cl1 == nullptr) {
1421 handleJniException(environment);
1422 }
1423 jmethodID method_loadClass = environment->GetMethodID(
1424 class_URLClassLoader, "loadClass",
1425 "(Ljava/lang/String;)Ljava/lang/Class;");
1426 if (method_loadClass == nullptr) {
1427 handleJniException(environment);
1428 }
1429 args[0].l = environment->NewStringUTF(
1430 "com.sun.star.lib.unoloader.UnoClassLoader");
1431 if (args[0].l == nullptr) {
1432 handleJniException(environment);
1433 }
1434 jclass class_UnoClassLoader = static_cast< jclass >(
1435 environment->CallObjectMethodA(cl1, method_loadClass, args));
1436 if (class_UnoClassLoader == nullptr) {
1437 handleJniException(environment);
1438 }
1439 jmethodID ctor_UnoClassLoader = environment->GetMethodID(
1440 class_UnoClassLoader, "<init>",
1441 "(Ljava/net/URL;[Ljava/net/URL;Ljava/lang/ClassLoader;)V");
1442 if (ctor_UnoClassLoader == nullptr) {
1443 handleJniException(environment);
1444 }
1445 args[0].l = base;
1446 args[1].l = classpath;
1447 args[2].l = cl1;
1448 jobject cl2 = environment->NewObjectA(
1449 class_UnoClassLoader, ctor_UnoClassLoader, args);
1450 if (cl2 == nullptr) {
1451 handleJniException(environment);
1452 }
1453 try {
1455 m_xVirtualMachine, cl2);
1457 css::uno::Any anyEx = cppu::getCaughtException();
1458 throw css::lang::WrappedTargetRuntimeException(
1459 "jvmaccess::UnoVirtualMachine::CreationException",
1460 getXWeak(), anyEx );
1461 }
1462}
1463
1464void JavaVirtualMachine::handleJniException(JNIEnv * environment) {
1465#if defined DBG_UTIL
1466 environment->ExceptionDescribe();
1467#else
1468 environment->ExceptionClear();
1469#endif
1470 throw css::uno::RuntimeException(
1471 "JNI exception occurred",
1472 getXWeak());
1473}
1474
1475
1476extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1478 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
1479{
1480 return cppu::acquire(new JavaVirtualMachine(context));
1481}
1482
1483
1484/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
sal_Int16 script
void getIsoLanguageScriptCountry(OUString &rLanguage, OUString &rScript, OUString &rCountry) const
mutable::osl::Mutex m_aMutex
void pushProp(const OUString &uString)
Definition: jvmargs.cxx:29
const ::std::vector< OUString > & getProperties() const
Definition: jvmargs.hxx:52
virtual void SAL_CALL elementInserted(css::container::ContainerEvent const &rEvent) override
Definition: javavm.cxx:882
virtual sal_Bool SAL_CALL isThreadAttached() override
Definition: javavm.cxx:806
virtual void SAL_CALL elementReplaced(css::container::ContainerEvent const &rEvent) override
Definition: javavm.cxx:895
virtual void SAL_CALL revokeThread() override
Definition: javavm.cxx:852
virtual ~JavaVirtualMachine() override
Definition: javavm.cxx:1123
void handleJniException(JNIEnv *environment)
Definition: javavm.cxx:1464
virtual void SAL_CALL elementRemoved(css::container::ContainerEvent const &rEvent) override
Definition: javavm.cxx:886
virtual void SAL_CALL registerThread() override
Definition: javavm.cxx:819
rtl::Reference< jvmaccess::VirtualMachine > m_xVirtualMachine
Definition: javavm.hxx:129
css::uno::Reference< css::container::XContainer > m_xJavaConfiguration
Definition: javavm.hxx:138
rtl::Reference< jvmaccess::UnoVirtualMachine > m_xUnoVirtualMachine
Definition: javavm.hxx:130
virtual sal_Bool SAL_CALL supportsService(OUString const &rServiceName) override
Definition: javavm.cxx:545
virtual OUString SAL_CALL getImplementationName() override
Definition: javavm.cxx:539
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: javavm.hxx:125
virtual css::uno::Any SAL_CALL getJavaVM(css::uno::Sequence< sal_Int8 > const &rProcessId) override
Definition: javavm.cxx:557
virtual sal_Bool SAL_CALL isVMEnabled() override
Definition: javavm.cxx:788
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: javavm.cxx:551
virtual void SAL_CALL disposing() override
Definition: javavm.cxx:1147
css::uno::Reference< css::container::XContainer > m_xInetConfiguration
Definition: javavm.hxx:136
void setINetSettingsInVM(bool set_reset)
Definition: javavm.cxx:1221
osl::ThreadData m_aAttachGuards
Definition: javavm.hxx:140
virtual void SAL_CALL initialize(css::uno::Sequence< css::uno::Any > const &rArguments) override
Definition: javavm.cxx:483
virtual sal_Bool SAL_CALL isVMStarted() override
Definition: javavm.cxx:779
void setUpUnoVirtualMachine(JNIEnv *environment)
Definition: javavm.cxx:1350
Any value
Reference< XMultiServiceFactory > xSMgr
OUString sName
javaFrameworkError jfw_findAndSelectJRE(std::unique_ptr< JavaInfo > *pInfo)
javaFrameworkError jfw_getSelectedJRE(std::unique_ptr< JavaInfo > *ppInfo)
javaFrameworkError jfw_startVM(JavaInfo const *pInfo, std::vector< OUString > const &arOptions, JavaVM **ppVM, JNIEnv **ppEnv)
javaFrameworkError jfw_getEnabled(bool *pbEnabled)
javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, bool *exist)
void const * base
bool m_bDisposed
std::mutex m_aMutex
#define JFW_REQUIRE_NEEDRESTART
javaFrameworkError
JFW_E_RUNNING_JVM
JFW_E_INVALID_SETTINGS
JFW_E_NONE
JFW_E_NEED_RESTART
JFW_E_NO_SELECT
JFW_E_JAVA_DISABLED
JFW_E_NO_JAVA_FOUND
JFW_E_VM_CREATION_FAILED
Sequence< PropertyValue > aArguments
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stoc_JavaVM_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: javavm.cxx:1477
#define TIMEZONE
Definition: javavm.cxx:77
void * p
sal_Int64 n
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
bool IsContextFlagActive(const OUString &sName)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
int i
index
JVMACCESS_DLLPUBLIC jobjectArray translateToUrls(css::uno::Reference< css::uno::XComponentContext > const &context, JNIEnv *environment, std::u16string_view classPath)
args
dictionary props
TransliterationModules tm
unsigned char sal_uInt8
unsigned char sal_Bool
sal_uInt16 sal_Unicode