Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / javavm / javavm.cxx
bloba4e9efe66e594c2a67124e578fa7b2bf61f87cb8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "javavm.hxx"
23 #include "interact.hxx"
24 #include "jvmargs.hxx"
26 #include <com/sun/star/beans/NamedValue.hpp>
27 #include <com/sun/star/beans/PropertyState.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/container/XContainer.hpp>
30 #include <com/sun/star/java/JavaNotFoundException.hpp>
31 #include <com/sun/star/java/InvalidJavaSettingsException.hpp>
32 #include <com/sun/star/java/RestartRequiredException.hpp>
33 #include <com/sun/star/java/JavaDisabledException.hpp>
34 #include <com/sun/star/java/JavaVMCreationFailureException.hpp>
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/lang/IllegalArgumentException.hpp>
37 #include <com/sun/star/lang/XEventListener.hpp>
38 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
39 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
40 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41 #include <com/sun/star/registry/XRegistryKey.hpp>
42 #include <com/sun/star/registry/XSimpleRegistry.hpp>
43 #include <com/sun/star/task/XInteractionHandler.hpp>
44 #include <com/sun/star/uno/Exception.hpp>
45 #include <com/sun/star/uno/Reference.hxx>
46 #include <com/sun/star/uno/RuntimeException.hpp>
47 #include <com/sun/star/uno/Sequence.hxx>
48 #include <com/sun/star/uno/XComponentContext.hpp>
49 #include <com/sun/star/uno/XCurrentContext.hpp>
50 #include <com/sun/star/uno/XInterface.hpp>
51 #include <com/sun/star/util/theMacroExpander.hpp>
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #include <cppuhelper/exc_hlp.hxx>
54 #include <cppuhelper/factory.hxx>
55 #include <cppuhelper/implbase.hxx>
56 #include <cppuhelper/implementationentry.hxx>
57 #include <cppuhelper/supportsservice.hxx>
58 #include <jvmaccess/classpath.hxx>
59 #include <jvmaccess/unovirtualmachine.hxx>
60 #include <jvmaccess/virtualmachine.hxx>
61 #include <osl/file.hxx>
62 #include <osl/thread.h>
63 #include <rtl/bootstrap.hxx>
64 #include <rtl/process.h>
65 #include <rtl/string.h>
66 #include <rtl/ustrbuf.hxx>
67 #include <rtl/ustring.h>
68 #include <rtl/ustring.hxx>
69 #include <rtl/uri.hxx>
70 #include <sal/types.h>
71 #include <uno/current_context.hxx>
72 #include <uno/environment.h>
73 #include <jvmfwk/framework.hxx>
74 #include <i18nlangtag/languagetag.hxx>
75 #include "jni.h"
77 #include <stack>
78 #include <string.h>
79 #include <time.h>
80 #include <memory>
81 #include <vector>
83 // Properties of the javavm can be put
84 // as a komma separated list in this
85 // environment variable
86 #ifdef UNIX
87 #define TIMEZONE "MEZ"
88 #else
89 #define TIMEZONE "MET"
90 #endif
92 /* Within this implementation of the com.sun.star.java.JavaVirtualMachine
93 * service and com.sun.star.java.theJavaVirtualMachine singleton, the method
94 * com.sun.star.java.XJavaVM.getJavaVM relies on the following:
95 * 1 The string "$URE_INTERNAL_JAVA_DIR/" is expanded via the
96 * com.sun.star.util.theMacroExpander singleton into an internal (see the
97 * com.sun.star.uri.ExternalUriReferenceTranslator service), hierarchical URI
98 * reference relative to which the URE JAR files can be addressed.
99 * 2 The string "$URE_INTERNAL_JAVA_CLASSPATH" is either not expandable via the
100 * com.sun.star.util.theMacroExpander singleton
101 * (com.sun.star.lang.IllegalArgumentException), or is expanded via the
102 * com.sun.star.util.theMacroExpander singleton into a list of zero or more
103 * internal (see the com.sun.star.uri.ExternalUriReferenceTranslator service)
104 * URIs, where any space characters (U+0020) are ignored (and, in particular,
105 * separate adjacent URIs).
106 * If either of these requirements is not met, getJavaVM raises a
107 * com.sun.star.uno.RuntimeException.
110 using stoc_javavm::JavaVirtualMachine;
112 namespace {
115 class NoJavaIniException: public css::uno::Exception
119 class SingletonFactory:
120 private cppu::WeakImplHelper< css::lang::XEventListener >
122 public:
123 static css::uno::Reference< css::uno::XInterface > getSingleton(
124 css::uno::Reference< css::uno::XComponentContext > const & rContext);
126 private:
127 SingletonFactory() {}
129 virtual ~SingletonFactory() override {}
131 SingletonFactory(const SingletonFactory&) = delete;
132 SingletonFactory& operator=(const SingletonFactory&) = delete;
134 virtual void SAL_CALL disposing(css::lang::EventObject const &) override;
136 static void dispose();
138 // TODO ok to keep these static?
139 static osl::Mutex m_aMutex;
140 static css::uno::Reference< css::uno::XInterface > m_xSingleton;
141 static bool m_bDisposed;
144 css::uno::Reference< css::uno::XInterface > SingletonFactory::getSingleton(
145 css::uno::Reference< css::uno::XComponentContext > const & rContext)
147 css::uno::Reference< css::uno::XInterface > xSingleton;
148 css::uno::Reference< css::lang::XComponent > xComponent;
150 osl::MutexGuard aGuard(m_aMutex);
151 if (!m_xSingleton.is())
153 if (m_bDisposed)
154 throw css::lang::DisposedException();
155 xComponent.set( rContext, css::uno::UNO_QUERY_THROW);
156 m_xSingleton = static_cast< cppu::OWeakObject * >(
157 new JavaVirtualMachine(rContext));
159 xSingleton = m_xSingleton;
161 if (xComponent.is())
164 xComponent->addEventListener(new SingletonFactory);
166 catch (...)
168 dispose();
169 throw;
171 return xSingleton;
174 void SAL_CALL SingletonFactory::disposing(css::lang::EventObject const &)
176 dispose();
179 void SingletonFactory::dispose()
181 css::uno::Reference< css::lang::XComponent > xComponent;
183 osl::MutexGuard aGuard(m_aMutex);
184 xComponent.set( m_xSingleton, css::uno::UNO_QUERY);
185 m_xSingleton.clear();
186 m_bDisposed = true;
188 if (xComponent.is())
189 xComponent->dispose();
192 osl::Mutex SingletonFactory::m_aMutex;
193 css::uno::Reference< css::uno::XInterface > SingletonFactory::m_xSingleton;
194 bool SingletonFactory::m_bDisposed = false;
196 OUString serviceGetImplementationName()
198 return OUString("com.sun.star.comp.stoc.JavaVirtualMachine");
201 css::uno::Sequence< OUString > serviceGetSupportedServiceNames()
203 return css::uno::Sequence< OUString > { "com.sun.star.java.JavaVirtualMachine" };
206 css::uno::Reference< css::uno::XInterface > SAL_CALL serviceCreateInstance(
207 css::uno::Reference< css::uno::XComponentContext > const & rContext)
209 // Only one single instance of this service is ever constructed, and is
210 // available until the component context used to create this instance is
211 // disposed. Afterwards, this function throws a DisposedException (as do
212 // all relevant methods on the single service instance).
213 return SingletonFactory::getSingleton(rContext);
216 cppu::ImplementationEntry const aServiceImplementation[]
217 = { { serviceCreateInstance,
218 serviceGetImplementationName,
219 serviceGetSupportedServiceNames,
220 cppu::createSingleComponentFactory,
221 nullptr, 0 },
222 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } };
224 typedef std::stack< jvmaccess::VirtualMachine::AttachGuard * > GuardStack;
226 extern "C" {
228 static void destroyAttachGuards(void * pData)
230 GuardStack * pStack = static_cast< GuardStack * >(pData);
231 if (pStack != nullptr)
233 while (!pStack->empty())
235 delete pStack->top();
236 pStack->pop();
238 delete pStack;
244 bool askForRetry(css::uno::Any const & rException)
246 css::uno::Reference< css::uno::XCurrentContext > xContext(
247 css::uno::getCurrentContext());
248 if (xContext.is())
250 css::uno::Reference< css::task::XInteractionHandler > xHandler;
251 xContext->getValueByName("java-vm.interaction-handler")
252 >>= xHandler;
253 if (xHandler.is())
255 rtl::Reference< stoc_javavm::InteractionRequest > xRequest(
256 new stoc_javavm::InteractionRequest(rException));
257 xHandler->handle(xRequest.get());
258 return xRequest->retry();
261 return false;
264 // Only gets the properties if the "Proxy Server" entry in the option dialog is
265 // set to manual (i.e. not to none)
266 /// @throws css::uno::Exception
267 void getINetPropsFromConfig(stoc_javavm::JVM * pjvm,
268 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
269 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
271 css::uno::Reference<css::uno::XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
272 "com.sun.star.configuration.ConfigurationRegistry",
273 xCtx );
274 if(!xConfRegistry.is()) throw css::uno::RuntimeException("javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
276 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(xConfRegistry, css::uno::UNO_QUERY_THROW);
277 xConfRegistry_simple->open("org.openoffice.Inet", true, false);
278 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
280 // if ooInetProxyType is not 0 then read the settings
281 css::uno::Reference<css::registry::XRegistryKey> proxyEnable= xRegistryRootKey->openKey("Settings/ooInetProxyType");
282 if( proxyEnable.is() && 0 != proxyEnable->getLongValue())
284 // read ftp proxy name
285 css::uno::Reference<css::registry::XRegistryKey> ftpProxy_name = xRegistryRootKey->openKey("Settings/ooInetFTPProxyName");
286 if(ftpProxy_name.is() && !ftpProxy_name->getStringValue().isEmpty()) {
287 OUString ftpHost = "ftp.proxyHost=" + ftpProxy_name->getStringValue();
289 // read ftp proxy port
290 css::uno::Reference<css::registry::XRegistryKey> ftpProxy_port = xRegistryRootKey->openKey("Settings/ooInetFTPProxyPort");
291 if(ftpProxy_port.is() && ftpProxy_port->getLongValue()) {
292 OUString ftpPort = "ftp.proxyPort=" + OUString::number(ftpProxy_port->getLongValue());
294 pjvm->pushProp(ftpHost);
295 pjvm->pushProp(ftpPort);
299 // read http proxy name
300 css::uno::Reference<css::registry::XRegistryKey> httpProxy_name = xRegistryRootKey->openKey("Settings/ooInetHTTPProxyName");
301 if(httpProxy_name.is() && !httpProxy_name->getStringValue().isEmpty()) {
302 OUString httpHost = "http.proxyHost=" + httpProxy_name->getStringValue();
304 // read http proxy port
305 css::uno::Reference<css::registry::XRegistryKey> httpProxy_port = xRegistryRootKey->openKey("Settings/ooInetHTTPProxyPort");
306 if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
307 OUString httpPort = "http.proxyPort=" + OUString::number(httpProxy_port->getLongValue());
309 pjvm->pushProp(httpHost);
310 pjvm->pushProp(httpPort);
314 // read https proxy name
315 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_name = xRegistryRootKey->openKey("Settings/ooInetHTTPSProxyName");
316 if(httpsProxy_name.is() && !httpsProxy_name->getStringValue().isEmpty()) {
317 OUString httpsHost = "https.proxyHost=" + httpsProxy_name->getStringValue();
319 // read https proxy port
320 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_port = xRegistryRootKey->openKey("Settings/ooInetHTTPSProxyPort");
321 if(httpsProxy_port.is() && httpsProxy_port->getLongValue()) {
322 OUString httpsPort = "https.proxyPort=" + OUString::number(httpsProxy_port->getLongValue());
324 pjvm->pushProp(httpsHost);
325 pjvm->pushProp(httpsPort);
329 // read nonProxyHosts
330 css::uno::Reference<css::registry::XRegistryKey> nonProxies_name = xRegistryRootKey->openKey("Settings/ooInetNoProxy");
331 if(nonProxies_name.is() && !nonProxies_name->getStringValue().isEmpty()) {
332 OUString value = nonProxies_name->getStringValue();
333 // replace the separator ";" by "|"
334 value = value.replace(';', '|');
336 OUString httpNonProxyHosts = "http.nonProxyHosts=" + value;
337 OUString ftpNonProxyHosts = "ftp.nonProxyHosts=" + value;
339 pjvm->pushProp(httpNonProxyHosts);
340 pjvm->pushProp(ftpNonProxyHosts);
343 xConfRegistry_simple->close();
346 /// @throws css::uno::Exception
347 void getDefaultLocaleFromConfig(
348 stoc_javavm::JVM * pjvm,
349 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
350 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
352 css::uno::Reference<css::uno::XInterface> xConfRegistry =
353 xSMgr->createInstanceWithContext( "com.sun.star.configuration.ConfigurationRegistry", xCtx );
354 if(!xConfRegistry.is())
355 throw css::uno::RuntimeException(
356 "javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
358 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
359 xConfRegistry, css::uno::UNO_QUERY_THROW);
360 xConfRegistry_simple->open("org.openoffice.Setup", true, false);
361 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
363 // Since 1.7 Java knows DISPLAY and FORMAT locales, which match our UI and
364 // system locale. See
365 // http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/file/569b1b644416/src/share/classes/java/util/Locale.java
366 // https://docs.oracle.com/javase/tutorial/i18n/locale/scope.html
367 // https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html
369 // Read UI language/locale.
370 css::uno::Reference<css::registry::XRegistryKey> xUILocale = xRegistryRootKey->openKey("L10N/ooLocale");
371 if(xUILocale.is() && !xUILocale->getStringValue().isEmpty()) {
372 LanguageTag aLanguageTag( xUILocale->getStringValue());
373 OUString language;
374 OUString script;
375 OUString country;
376 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
377 // Locale.forLanguageTag() are used, or non-standardized variant field
378 // content which we ignore.
379 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
381 if(!language.isEmpty()) {
382 OUString prop = "user.language=" + language;
383 pjvm->pushProp(prop);
386 // As of Java 7 also script is supported.
387 if(!script.isEmpty()) {
388 OUString prop = "user.script=" + script;
389 pjvm->pushProp(prop);
392 if(!country.isEmpty()) {
393 OUString prop = "user.country=" + country;
394 pjvm->pushProp(prop);
397 // Java 7 DISPLAY category is our UI language/locale.
398 if(!language.isEmpty()) {
399 OUString prop = "user.language.display=" + language;
400 pjvm->pushProp(prop);
403 if(!script.isEmpty()) {
404 OUString prop = "user.script.display=" + script;
405 pjvm->pushProp(prop);
408 if(!country.isEmpty()) {
409 OUString prop = "user.country.display=" + country;
410 pjvm->pushProp(prop);
414 // Read system locale.
415 css::uno::Reference<css::registry::XRegistryKey> xLocale = xRegistryRootKey->openKey("L10N/ooSetupSystemLocale");
416 if(xLocale.is() && !xLocale->getStringValue().isEmpty()) {
417 LanguageTag aLanguageTag( xLocale->getStringValue());
418 OUString language;
419 OUString script;
420 OUString country;
421 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
422 // Locale.forLanguageTag() are used, or non-standardized variant field
423 // content which we ignore.
424 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
426 // Java 7 FORMAT category is our system locale.
427 if(!language.isEmpty()) {
428 OUString prop = "user.language.format=" + language;
429 pjvm->pushProp(prop);
432 if(!script.isEmpty()) {
433 OUString prop = "user.script.format=" + script;
434 pjvm->pushProp(prop);
437 if(!country.isEmpty()) {
438 OUString prop = "user.country.format=" + country;
439 pjvm->pushProp(prop);
443 xConfRegistry_simple->close();
446 /// @throws css::uno::Exception
447 void getJavaPropsFromSafetySettings(
448 stoc_javavm::JVM * pjvm,
449 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
450 const css::uno::Reference<css::uno::XComponentContext> &xCtx)
452 css::uno::Reference<css::uno::XInterface> xConfRegistry =
453 xSMgr->createInstanceWithContext(
454 "com.sun.star.configuration.ConfigurationRegistry",
455 xCtx);
456 if(!xConfRegistry.is())
457 throw css::uno::RuntimeException(
458 "javavm.cxx: couldn't get ConfigurationRegistry", nullptr);
460 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
461 xConfRegistry, css::uno::UNO_QUERY_THROW);
462 xConfRegistry_simple->open(
463 "org.openoffice.Office.Java",
464 true, false);
465 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey =
466 xConfRegistry_simple->getRootKey();
468 if (xRegistryRootKey.is())
470 css::uno::Reference<css::registry::XRegistryKey> key_NetAccess= xRegistryRootKey->openKey("VirtualMachine/NetAccess");
471 if (key_NetAccess.is())
473 sal_Int32 val= key_NetAccess->getLongValue();
474 OUString sVal;
475 switch( val)
477 case 0: sVal = "host";
478 break;
479 case 1: sVal = "unrestricted";
480 break;
481 case 3: sVal = "none";
482 break;
484 OUString sProperty("appletviewer.security.mode=");
485 sProperty= sProperty + sVal;
486 pjvm->pushProp(sProperty);
488 css::uno::Reference<css::registry::XRegistryKey> key_CheckSecurity= xRegistryRootKey->openKey(
489 "VirtualMachine/Security");
490 if( key_CheckSecurity.is())
492 bool val = (bool) key_CheckSecurity->getLongValue();
493 OUString sProperty("stardiv.security.disableSecurity=");
494 if( val)
495 sProperty= sProperty + "false";
496 else
497 sProperty= sProperty + "true";
498 pjvm->pushProp( sProperty);
501 xConfRegistry_simple->close();
504 void setTimeZone(stoc_javavm::JVM * pjvm) throw() {
505 /* A Bug in the Java function
506 ** struct Hjava_util_Properties * java_lang_System_initProperties(
507 ** struct Hjava_lang_System *this,
508 ** struct Hjava_util_Properties *props);
509 ** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
511 struct tm *tmData;
512 time_t clock = time(nullptr);
513 tzset();
514 tmData = localtime(&clock);
515 #ifdef MACOSX
516 char * p = tmData->tm_zone;
517 #elif defined(_MSC_VER)
518 char * p = _tzname[0];
519 (void)tmData;
520 #else
521 char * p = tzname[0];
522 (void)tmData;
523 #endif
525 if (!strcmp(TIMEZONE, p))
526 pjvm->pushProp("user.timezone=ECT");
529 /// @throws css::uno::Exception
530 void initVMConfiguration(
531 stoc_javavm::JVM * pjvm,
532 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
533 const css::uno::Reference<css::uno::XComponentContext > &xCtx)
535 stoc_javavm::JVM jvm;
536 try {
537 getINetPropsFromConfig(&jvm, xSMgr, xCtx);
539 catch(const css::uno::Exception & exception) {
540 SAL_INFO("stoc", "can not get INETProps because of >" << exception.Message << "<");
543 try {
544 getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
546 catch(const css::uno::Exception & exception) {
547 SAL_INFO("stoc", "can not get locale because of >" << exception.Message << "<");
552 getJavaPropsFromSafetySettings(&jvm, xSMgr, xCtx);
554 catch(const css::uno::Exception & exception) {
555 SAL_INFO("stoc", "couldn't get safety settings because of >" << exception.Message << "<");
558 *pjvm= jvm;
560 // rhbz#1285356, native look will be gtk2, which crashes
561 // when gtk3 is already loaded. Until there is a solution
562 // java-side force look and feel to something that doesn't
563 // crash when we are using gtk3
564 if (getenv("STOC_FORCE_SYSTEM_LAF"))
565 pjvm->pushProp("swing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel");
567 setTimeZone(pjvm);
570 class DetachCurrentThread {
571 public:
572 explicit DetachCurrentThread(JavaVM * jvm): m_jvm(jvm) {}
574 ~DetachCurrentThread() {
575 if (m_jvm->DetachCurrentThread() != 0) {
576 OSL_ASSERT(false);
580 DetachCurrentThread(const DetachCurrentThread&) = delete;
581 DetachCurrentThread& operator=(const DetachCurrentThread&) = delete;
583 private:
584 JavaVM * m_jvm;
589 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL javavm_component_getFactory(sal_Char const * pImplName,
590 void * pServiceManager,
591 void * pRegistryKey)
593 return cppu::component_getFactoryHelper(pImplName, pServiceManager,
594 pRegistryKey,
595 aServiceImplementation);
598 JavaVirtualMachine::JavaVirtualMachine(
599 css::uno::Reference< css::uno::XComponentContext > const & rContext):
600 JavaVirtualMachine_Impl(m_aMutex),
601 m_xContext(rContext),
602 m_bDisposed(false),
603 m_pJavaVm(nullptr),
604 m_aAttachGuards(destroyAttachGuards) // TODO check for validity
607 void SAL_CALL
608 JavaVirtualMachine::initialize(css::uno::Sequence< css::uno::Any > const &
609 rArguments)
611 osl::MutexGuard aGuard(m_aMutex);
612 if (m_bDisposed)
613 throw css::lang::DisposedException(
614 "", static_cast< cppu::OWeakObject * >(this));
615 if (m_xUnoVirtualMachine.is())
616 throw css::uno::RuntimeException(
617 "bad call to initialize",
618 static_cast< cppu::OWeakObject * >(this));
619 css::beans::NamedValue val;
620 if (rArguments.getLength() == 1 && (rArguments[0] >>= val) && val.Name == "UnoVirtualMachine" )
622 OSL_ENSURE(
623 sizeof (sal_Int64) >= sizeof (jvmaccess::UnoVirtualMachine *),
624 "Pointer cannot be represented as sal_Int64");
625 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
626 static_cast< jvmaccess::UnoVirtualMachine * >(nullptr));
627 val.Value >>= nPointer;
628 m_xUnoVirtualMachine =
629 reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer);
630 } else {
631 OSL_ENSURE(
632 sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *),
633 "Pointer cannot be represented as sal_Int64");
634 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
635 static_cast< jvmaccess::VirtualMachine * >(nullptr));
636 if (rArguments.getLength() == 1)
637 rArguments[0] >>= nPointer;
638 rtl::Reference< jvmaccess::VirtualMachine > vm(
639 reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer));
640 if (vm.is()) {
641 try {
642 m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(vm, nullptr);
643 } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
644 throw css::uno::RuntimeException(
645 "jvmaccess::UnoVirtualMachine::CreationException",
646 static_cast< cppu::OWeakObject * >(this));
650 if (!m_xUnoVirtualMachine.is()) {
651 throw css::lang::IllegalArgumentException(
652 "sequence of exactly one any containing either (a) a"
653 " com.sun.star.beans.NamedValue with Name"
654 " \"UnoVirtualMachine\" and Value a hyper representing a"
655 " non-null pointer to a jvmaccess:UnoVirtualMachine, or (b)"
656 " a hyper representing a non-null pointer to a"
657 " jvmaccess::VirtualMachine required",
658 static_cast< cppu::OWeakObject * >(this), 0);
660 m_xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
663 OUString SAL_CALL JavaVirtualMachine::getImplementationName()
665 return serviceGetImplementationName();
668 sal_Bool SAL_CALL
669 JavaVirtualMachine::supportsService(OUString const & rServiceName)
671 return cppu::supportsService(this, rServiceName);
674 css::uno::Sequence< OUString > SAL_CALL
675 JavaVirtualMachine::getSupportedServiceNames()
677 return serviceGetSupportedServiceNames();
680 css::uno::Any SAL_CALL
681 JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
683 osl::MutexGuard aGuard(m_aMutex);
684 if (m_bDisposed)
685 throw css::lang::DisposedException(
686 "", static_cast< cppu::OWeakObject * >(this));
687 css::uno::Sequence< sal_Int8 > aId(16);
688 rtl_getGlobalProcessId(reinterpret_cast< sal_uInt8 * >(aId.getArray()));
689 enum ReturnType {
690 RETURN_JAVAVM, RETURN_VIRTUALMACHINE, RETURN_UNOVIRTUALMACHINE };
691 ReturnType returnType =
692 rProcessId.getLength() == 17 && rProcessId[16] == 0
693 ? RETURN_VIRTUALMACHINE
694 : rProcessId.getLength() == 17 && rProcessId[16] == 1
695 ? RETURN_UNOVIRTUALMACHINE
696 : RETURN_JAVAVM;
697 css::uno::Sequence< sal_Int8 > aProcessId(rProcessId);
698 if (returnType != RETURN_JAVAVM)
699 aProcessId.realloc(16);
700 if (aId != aProcessId)
701 return css::uno::Any();
703 std::unique_ptr<JavaInfo> info;
704 while (!m_xVirtualMachine.is()) // retry until successful
706 stoc_javavm::JVM aJvm;
707 initVMConfiguration(&aJvm, m_xContext->getServiceManager(),
708 m_xContext);
709 const std::vector<OUString> & props = aJvm.getProperties();
710 std::vector<OUString> options;
711 for (auto const & i: props)
713 options.push_back(i.startsWith("-") ? i : "-D" + i);
716 JNIEnv * pMainThreadEnv = nullptr;
717 javaFrameworkError errcode = JFW_E_NONE;
719 if (getenv("STOC_FORCE_NO_JRE"))
720 errcode = JFW_E_NO_SELECT;
721 else
722 errcode = jfw_startVM(info.get(), options, & m_pJavaVm,
723 & pMainThreadEnv);
725 bool bStarted = false;
726 switch (errcode)
728 case JFW_E_NONE: bStarted = true; break;
729 case JFW_E_NO_SELECT:
731 // No Java configured. We silently run the Java configuration
732 info.reset();
733 javaFrameworkError errFind = jfw_findAndSelectJRE(&info);
734 if (getenv("STOC_FORCE_NO_JRE"))
735 errFind = JFW_E_NO_JAVA_FOUND;
736 if (errFind == JFW_E_NONE)
738 continue;
740 else if (errFind == JFW_E_NO_JAVA_FOUND)
743 //Warning MessageBox:
744 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task.
745 //Please install a JRE and restart %PRODUCTNAME.
746 css::java::JavaNotFoundException exc(
747 "JavaVirtualMachine::getJavaVM failed because"
748 " No suitable JRE found!",
749 static_cast< cppu::OWeakObject * >(this));
750 askForRetry(css::uno::makeAny(exc));
751 return css::uno::Any();
753 else
755 //An unexpected error occurred
756 throw css::uno::RuntimeException(
757 "[JavaVirtualMachine]:An unexpected error occurred"
758 " while searching for a Java!", nullptr);
761 case JFW_E_INVALID_SETTINGS:
763 //Warning MessageBox:
764 // The %PRODUCTNAME configuration has been changed. Under Tools
765 // - Options - %PRODUCTNAME - Java, select the Java runtime environment
766 // you want to have used by %PRODUCTNAME.
767 css::java::InvalidJavaSettingsException exc(
768 "JavaVirtualMachine::getJavaVM failed because"
769 " Java settings have changed!",
770 static_cast< cppu::OWeakObject * >(this));
771 askForRetry(css::uno::makeAny(exc));
772 return css::uno::Any();
774 case JFW_E_JAVA_DISABLED:
776 //QueryBox:
777 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform
778 //this task. However, use of a JRE has been disabled. Do you want to
779 //enable the use of a JRE now?
780 css::java::JavaDisabledException exc(
781 "JavaVirtualMachine::getJavaVM failed because Java is disabled!",
782 static_cast< cppu::OWeakObject * >(this));
783 if( ! askForRetry(css::uno::makeAny(exc)))
784 return css::uno::Any();
785 continue;
787 case JFW_E_VM_CREATION_FAILED:
789 //If the creation failed because the JRE has been uninstalled then
790 //we search another one. As long as there is a javaldx, we should
791 //never come into this situation. javaldx checks always if the JRE
792 //still exist.
793 std::unique_ptr<JavaInfo> aJavaInfo;
794 if (JFW_E_NONE == jfw_getSelectedJRE(&aJavaInfo))
796 bool bExist = false;
797 if (JFW_E_NONE == jfw_existJRE(aJavaInfo.get(), &bExist))
799 if (!bExist
800 && ! (aJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
802 info.reset();
803 javaFrameworkError errFind = jfw_findAndSelectJRE(
804 &info);
805 if (errFind == JFW_E_NONE)
807 continue;
813 //Error: %PRODUCTNAME requires a Java
814 //runtime environment (JRE) to perform this task. The selected JRE
815 //is defective. Please select another version or install a new JRE
816 //and select it under Tools - Options - %PRODUCTNAME - Java.
817 css::java::JavaVMCreationFailureException exc(
818 "JavaVirtualMachine::getJavaVM failed because Java is defective!",
819 static_cast< cppu::OWeakObject * >(this), 0);
820 askForRetry(css::uno::makeAny(exc));
821 return css::uno::Any();
823 case JFW_E_RUNNING_JVM:
825 //This service should make sure that we do not start java twice.
826 OSL_ASSERT(false);
827 break;
829 case JFW_E_NEED_RESTART:
831 //Error:
832 //For the selected Java runtime environment to work properly,
833 //%PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.
834 css::java::RestartRequiredException exc(
835 "JavaVirtualMachine::getJavaVM failed because "
836 "Office must be restarted before Java can be used!",
837 static_cast< cppu::OWeakObject * >(this));
838 askForRetry(css::uno::makeAny(exc));
839 return css::uno::Any();
841 default:
842 //RuntimeException: error is somewhere in the java framework.
843 //An unexpected error occurred
844 throw css::uno::RuntimeException(
845 "[JavaVirtualMachine]:An unexpected error occurred"
846 " while starting Java!", nullptr);
849 if (bStarted)
852 DetachCurrentThread detach(m_pJavaVm);
853 // necessary to make debugging work; this thread will be
854 // suspended when the destructor of detach returns
855 m_xVirtualMachine = new jvmaccess::VirtualMachine(
856 m_pJavaVm, JNI_VERSION_1_2, true, pMainThreadEnv);
857 setUpUnoVirtualMachine(pMainThreadEnv);
859 // Listen for changes in the configuration (e.g. proxy settings):
860 // TODO this is done too late; changes to the configuration done
861 // after the above call to initVMConfiguration are lost
862 registerConfigChangesListener();
864 break;
867 if (!m_xUnoVirtualMachine.is()) {
868 try {
869 jvmaccess::VirtualMachine::AttachGuard guard(m_xVirtualMachine);
870 setUpUnoVirtualMachine(guard.getEnvironment());
871 } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
872 throw css::uno::RuntimeException(
873 "jvmaccess::VirtualMachine::AttachGuard::CreationException occurred",
874 static_cast< cppu::OWeakObject * >(this));
877 switch (returnType) {
878 default: // RETURN_JAVAVM
879 if (m_pJavaVm == nullptr) {
880 throw css::uno::RuntimeException(
881 "JavaVirtualMachine service was initialized in a way"
882 " that the requested JavaVM pointer is not available",
883 static_cast< cppu::OWeakObject * >(this));
885 return css::uno::makeAny(reinterpret_cast< sal_IntPtr >(m_pJavaVm));
886 case RETURN_VIRTUALMACHINE:
887 OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
888 return css::uno::makeAny(
889 reinterpret_cast< sal_Int64 >(
890 m_xUnoVirtualMachine->getVirtualMachine().get()));
891 case RETURN_UNOVIRTUALMACHINE:
892 OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
893 return css::uno::makeAny(
894 reinterpret_cast< sal_Int64 >(m_xUnoVirtualMachine.get()));
898 sal_Bool SAL_CALL JavaVirtualMachine::isVMStarted()
900 osl::MutexGuard aGuard(m_aMutex);
901 if (m_bDisposed)
902 throw css::lang::DisposedException(
903 OUString(), static_cast< cppu::OWeakObject * >(this));
904 return m_xUnoVirtualMachine.is();
907 sal_Bool SAL_CALL JavaVirtualMachine::isVMEnabled()
910 osl::MutexGuard aGuard(m_aMutex);
911 if (m_bDisposed)
912 throw css::lang::DisposedException(
913 OUString(), static_cast< cppu::OWeakObject * >(this));
915 // stoc_javavm::JVM aJvm;
916 // initVMConfiguration(&aJvm, m_xContext->getServiceManager(), m_xContext);
917 // return aJvm.isEnabled();
918 //ToDo
919 bool bEnabled = false;
920 if (jfw_getEnabled( & bEnabled) != JFW_E_NONE)
921 throw css::uno::RuntimeException();
922 return bEnabled;
925 sal_Bool SAL_CALL JavaVirtualMachine::isThreadAttached()
927 osl::MutexGuard aGuard(m_aMutex);
928 if (m_bDisposed)
929 throw css::lang::DisposedException(
930 OUString(), static_cast< cppu::OWeakObject * >(this));
931 // TODO isThreadAttached only returns true if the thread was attached via
932 // registerThread:
933 GuardStack * pStack
934 = static_cast< GuardStack * >(m_aAttachGuards.getData());
935 return pStack != nullptr && !pStack->empty();
938 void SAL_CALL JavaVirtualMachine::registerThread()
940 osl::MutexGuard aGuard(m_aMutex);
941 if (m_bDisposed)
942 throw css::lang::DisposedException(
943 "", static_cast< cppu::OWeakObject * >(this));
944 if (!m_xUnoVirtualMachine.is())
945 throw css::uno::RuntimeException(
946 "JavaVirtualMachine::registerThread: null VirtualMachine",
947 static_cast< cppu::OWeakObject * >(this));
948 GuardStack * pStack
949 = static_cast< GuardStack * >(m_aAttachGuards.getData());
950 if (pStack == nullptr)
952 pStack = new GuardStack;
953 m_aAttachGuards.setData(pStack);
957 pStack->push(
958 new jvmaccess::VirtualMachine::AttachGuard(
959 m_xUnoVirtualMachine->getVirtualMachine()));
961 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
963 throw css::uno::RuntimeException(
964 "JavaVirtualMachine::registerThread: jvmaccess::"
965 "VirtualMachine::AttachGuard::CreationException",
966 static_cast< cppu::OWeakObject * >(this));
970 void SAL_CALL JavaVirtualMachine::revokeThread()
972 osl::MutexGuard aGuard(m_aMutex);
973 if (m_bDisposed)
974 throw css::lang::DisposedException(
975 "", static_cast< cppu::OWeakObject * >(this));
976 if (!m_xUnoVirtualMachine.is())
977 throw css::uno::RuntimeException(
978 "JavaVirtualMachine::revokeThread: null VirtualMachine",
979 static_cast< cppu::OWeakObject * >(this));
980 GuardStack * pStack
981 = static_cast< GuardStack * >(m_aAttachGuards.getData());
982 if (pStack == nullptr || pStack->empty())
983 throw css::uno::RuntimeException(
984 "JavaVirtualMachine::revokeThread: no matching registerThread",
985 static_cast< cppu::OWeakObject * >(this));
986 delete pStack->top();
987 pStack->pop();
990 void SAL_CALL
991 JavaVirtualMachine::disposing(css::lang::EventObject const & rSource)
993 osl::MutexGuard aGuard(m_aMutex);
994 if (rSource.Source == m_xInetConfiguration)
995 m_xInetConfiguration.clear();
996 if (rSource.Source == m_xJavaConfiguration)
997 m_xJavaConfiguration.clear();
1000 void SAL_CALL JavaVirtualMachine::elementInserted(
1001 css::container::ContainerEvent const &)
1004 void SAL_CALL JavaVirtualMachine::elementRemoved(
1005 css::container::ContainerEvent const &)
1008 // If a user changes the setting, for example for proxy settings, then this
1009 // function will be called from the configuration manager. Even if the .xml
1010 // file does not contain an entry yet and that entry has to be inserted, this
1011 // function will be called. We call java.lang.System.setProperty for the new
1012 // values.
1013 void SAL_CALL JavaVirtualMachine::elementReplaced(
1014 css::container::ContainerEvent const & rEvent)
1016 // TODO Using the new value stored in rEvent is wrong here. If two threads
1017 // receive different elementReplaced calls in quick succession, it is
1018 // unspecified which changes the JVM's system properties last. A correct
1019 // solution must atomically (i.e., protected by a mutex) read the latest
1020 // value from the configuration and set it as a system property at the JVM.
1022 OUString aAccessor;
1023 rEvent.Accessor >>= aAccessor;
1024 OUString aPropertyName;
1025 OUString aPropertyName2;
1026 OUString aPropertyValue;
1027 bool bSecurityChanged = false;
1028 if ( aAccessor == "ooInetProxyType" )
1030 // Proxy none, manually
1031 sal_Int32 value = 0;
1032 rEvent.Element >>= value;
1033 setINetSettingsInVM(value != 0);
1034 return;
1036 else if ( aAccessor == "ooInetHTTPProxyName" )
1038 aPropertyName = "http.proxyHost";
1039 rEvent.Element >>= aPropertyValue;
1041 else if ( aAccessor == "ooInetHTTPProxyPort" )
1043 aPropertyName = "http.proxyPort";
1044 sal_Int32 n = 0;
1045 rEvent.Element >>= n;
1046 aPropertyValue = OUString::number(n);
1048 else if ( aAccessor == "ooInetHTTPSProxyName" )
1050 aPropertyName = "https.proxyHost";
1051 rEvent.Element >>= aPropertyValue;
1053 else if ( aAccessor == "ooInetHTTPSProxyPort" )
1055 aPropertyName = "https.proxyPort";
1056 sal_Int32 n = 0;
1057 rEvent.Element >>= n;
1058 aPropertyValue = OUString::number(n);
1060 else if ( aAccessor == "ooInetFTPProxyName" )
1062 aPropertyName = "ftp.proxyHost";
1063 rEvent.Element >>= aPropertyValue;
1065 else if ( aAccessor == "ooInetFTPProxyPort" )
1067 aPropertyName = "ftp.proxyPort";
1068 sal_Int32 n = 0;
1069 rEvent.Element >>= n;
1070 aPropertyValue = OUString::number(n);
1072 else if ( aAccessor == "ooInetNoProxy" )
1074 aPropertyName = "http.nonProxyHosts";
1075 aPropertyName2 = "ftp.nonProxyHosts";
1076 rEvent.Element >>= aPropertyValue;
1077 aPropertyValue = aPropertyValue.replace(';', '|');
1079 else if ( aAccessor == "NetAccess" )
1081 aPropertyName = "appletviewer.security.mode";
1082 sal_Int32 n = 0;
1083 if (rEvent.Element >>= n)
1084 switch (n)
1086 case 0:
1087 aPropertyValue = "host";
1088 break;
1089 case 1:
1090 aPropertyValue = "unrestricted";
1091 break;
1092 case 3:
1093 aPropertyValue = "none";
1094 break;
1096 else
1097 return;
1098 bSecurityChanged = true;
1100 else if ( aAccessor == "Security" )
1102 aPropertyName = "stardiv.security.disableSecurity";
1103 bool b;
1104 if (rEvent.Element >>= b)
1105 if (b)
1106 aPropertyValue = "false";
1107 else
1108 aPropertyValue = "true";
1109 else
1110 return;
1111 bSecurityChanged = true;
1113 else
1114 return;
1116 rtl::Reference< jvmaccess::VirtualMachine > xVirtualMachine;
1118 osl::MutexGuard aGuard(m_aMutex);
1119 if (m_xUnoVirtualMachine.is()) {
1120 xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
1123 if (xVirtualMachine.is())
1127 jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
1128 xVirtualMachine);
1129 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1131 // call java.lang.System.setProperty
1132 // String setProperty( String key, String value)
1133 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1134 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/lang/System", nullptr);
1135 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1136 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.setProperty", nullptr);
1138 jstring jsPropName= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName.getStr()), aPropertyName.getLength());
1139 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1141 // remove the property if it does not have a value ( user left the dialog field empty)
1142 // or if the port is set to 0
1143 aPropertyValue= aPropertyValue.trim();
1144 if( aPropertyValue.isEmpty() ||
1145 ( ( aPropertyName == "ftp.proxyPort" || aPropertyName == "http.proxyPort" /*|| aPropertyName == "socksProxyPort"*/ ) && aPropertyValue == "0" )
1148 // call java.lang.System.getProperties
1149 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1150 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getProperties", nullptr);
1151 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1152 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.getProperties", nullptr);
1153 // call java.util.Properties.remove
1154 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1155 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/util/Properties", nullptr);
1156 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1157 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.util.Properties.remove", nullptr);
1158 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName);
1160 // special case for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1161 // has a value for two java properties
1162 if (!aPropertyName2.isEmpty())
1164 jstring jsPropName2= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName2.getStr()), aPropertyName2.getLength());
1165 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1166 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName2);
1169 else
1171 // Change the Value of the property
1172 jstring jsPropValue= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyValue.getStr()), aPropertyValue.getLength());
1173 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1174 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName, jsPropValue);
1175 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1177 // special case for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1178 // has a value for two java properties
1179 if (!aPropertyName2.isEmpty())
1181 jstring jsPropName2= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName2.getStr()), aPropertyName2.getLength());
1182 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1183 jsPropValue= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyValue.getStr()), aPropertyValue.getLength());
1184 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1185 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName2, jsPropValue);
1186 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1190 // If the settings for Security and NetAccess changed then we have to notify the SandboxSecurity
1191 // SecurityManager
1192 // call System.getSecurityManager()
1193 if (bSecurityChanged)
1195 jmethodID jmGetSecur= pJNIEnv->GetStaticMethodID( jcSystem,"getSecurityManager","()Ljava/lang/SecurityManager;");
1196 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getSecurityManager", nullptr);
1197 jobject joSecur= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetSecur);
1198 if (joSecur != nullptr)
1200 // Make sure the SecurityManager is our SandboxSecurity
1201 // FindClass("com.sun.star.lib.sandbox.SandboxSecurityManager" only worked at the first time
1202 // this code was executed. Maybe it is a security feature. However, all attempts to debug the
1203 // SandboxSecurity class (maybe the VM invokes checkPackageAccess) failed.
1204 // jclass jcSandboxSec= pJNIEnv->FindClass("com.sun.star.lib.sandbox.SandboxSecurity");
1205 // if(pJNIEnv->ExceptionOccurred()) throw RuntimeException("JNI:FindClass com.sun.star.lib.sandbox.SandboxSecurity");
1206 // jboolean bIsSand= pJNIEnv->IsInstanceOf( joSecur, jcSandboxSec);
1207 // The SecurityManagers class Name must be com.sun.star.lib.sandbox.SandboxSecurity
1208 jclass jcSec= pJNIEnv->GetObjectClass( joSecur);
1209 jclass jcClass= pJNIEnv->FindClass("java/lang/Class");
1210 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java.lang.Class", nullptr);
1211 jmethodID jmName= pJNIEnv->GetMethodID( jcClass,"getName","()Ljava/lang/String;");
1212 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.lang.Class.getName", nullptr);
1213 jstring jsClass= static_cast<jstring>(pJNIEnv->CallObjectMethod( jcSec, jmName));
1214 const jchar* jcharName= pJNIEnv->GetStringChars( jsClass, nullptr);
1215 OUString sName(reinterpret_cast<sal_Unicode const *>(jcharName));
1216 bool bIsSandbox;
1217 if ( sName == "com.sun.star.lib.sandbox.SandboxSecurity" )
1218 bIsSandbox= true;
1219 else
1220 bIsSandbox= false;
1221 pJNIEnv->ReleaseStringChars( jsClass, jcharName);
1223 if (bIsSandbox)
1225 // call SandboxSecurity.reset
1226 jmethodID jmReset= pJNIEnv->GetMethodID( jcSec,"reset","()V");
1227 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID com.sun.star.lib.sandbox.SandboxSecurity.reset", nullptr);
1228 pJNIEnv->CallVoidMethod( joSecur, jmReset);
1229 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallVoidMethod com.sun.star.lib.sandbox.SandboxSecurity.reset", nullptr);
1234 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1236 throw css::uno::RuntimeException(
1237 "jvmaccess::VirtualMachine::AttachGuard::CreationException",
1238 nullptr);
1243 JavaVirtualMachine::~JavaVirtualMachine()
1245 if (m_xInetConfiguration.is())
1246 // We should never get here, but just in case...
1249 m_xInetConfiguration->removeContainerListener(this);
1251 catch (css::uno::Exception &)
1253 OSL_FAIL("com.sun.star.uno.Exception caught");
1255 if (m_xJavaConfiguration.is())
1256 // We should never get here, but just in case...
1259 m_xJavaConfiguration->removeContainerListener(this);
1261 catch (css::uno::Exception &)
1263 OSL_FAIL("com.sun.star.uno.Exception caught");
1267 void SAL_CALL JavaVirtualMachine::disposing()
1269 css::uno::Reference< css::container::XContainer > xContainer1;
1270 css::uno::Reference< css::container::XContainer > xContainer2;
1272 osl::MutexGuard aGuard(m_aMutex);
1273 m_bDisposed = true;
1274 xContainer1 = m_xInetConfiguration;
1275 m_xInetConfiguration.clear();
1276 xContainer2 = m_xJavaConfiguration;
1277 m_xJavaConfiguration.clear();
1279 if (xContainer1.is())
1280 xContainer1->removeContainerListener(this);
1281 if (xContainer2.is())
1282 xContainer2->removeContainerListener(this);
1285 /*We listen to changes in the configuration. For example, the user changes the proxy
1286 settings in the options dialog (menu tools). Then we are notified of this change and
1287 if the java vm is already running we change the properties (System.lang.System.setProperties)
1288 through JNI.
1289 To receive notifications this class implements XContainerListener.
1291 void JavaVirtualMachine::registerConfigChangesListener()
1295 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
1296 m_xContext->getValueByName(
1297 "/singletons/com.sun.star.configuration.theDefaultProvider"),
1298 css::uno::UNO_QUERY);
1300 if (xConfigProvider.is())
1302 // We register this instance as listener to changes in org.openoffice.Inet/Settings
1303 // arguments for ConfigurationAccess
1304 css::uno::Sequence< css::uno::Any > aArguments(2);
1305 aArguments[0] <<= css::beans::PropertyValue(
1306 "nodepath",
1308 css::uno::makeAny(OUString("org.openoffice.Inet/Settings")),
1309 css::beans::PropertyState_DIRECT_VALUE);
1310 // depth: -1 means unlimited
1311 aArguments[1] <<= css::beans::PropertyValue(
1312 "depth",
1314 css::uno::makeAny( (sal_Int32)-1),
1315 css::beans::PropertyState_DIRECT_VALUE);
1317 m_xInetConfiguration.set(
1318 xConfigProvider->createInstanceWithArguments(
1319 "com.sun.star.configuration.ConfigurationAccess",
1320 aArguments),
1321 css::uno::UNO_QUERY);
1323 if (m_xInetConfiguration.is())
1324 m_xInetConfiguration->addContainerListener(this);
1326 // now register as listener to changes in org.openoffice.Java/VirtualMachine
1327 css::uno::Sequence< css::uno::Any > aArguments2(2);
1328 aArguments2[0] <<= css::beans::PropertyValue(
1329 "nodepath",
1331 css::uno::makeAny(OUString("org.openoffice.Office.Java/VirtualMachine")),
1332 css::beans::PropertyState_DIRECT_VALUE);
1333 // depth: -1 means unlimited
1334 aArguments2[1] <<= css::beans::PropertyValue(
1335 "depth",
1337 css::uno::makeAny( (sal_Int32)-1),
1338 css::beans::PropertyState_DIRECT_VALUE);
1340 m_xJavaConfiguration.set(
1341 xConfigProvider->createInstanceWithArguments(
1342 "com.sun.star.configuration.ConfigurationAccess",
1343 aArguments2),
1344 css::uno::UNO_QUERY);
1346 if (m_xJavaConfiguration.is())
1347 m_xJavaConfiguration->addContainerListener(this);
1349 }catch(const css::uno::Exception & e)
1351 SAL_INFO("stoc", "could not set up listener for Configuration because of >" << e.Message << "<");
1355 // param true: all Inet setting are set as Java Properties on a live VM.
1356 // false: the Java net properties are set to empty value.
1357 void JavaVirtualMachine::setINetSettingsInVM(bool set_reset)
1359 osl::MutexGuard aGuard(m_aMutex);
1362 if (m_xUnoVirtualMachine.is())
1364 jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
1365 m_xUnoVirtualMachine->getVirtualMachine());
1366 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1368 // The Java Properties
1369 OUString sFtpProxyHost("ftp.proxyHost");
1370 OUString sFtpProxyPort("ftp.proxyPort");
1371 OUString sFtpNonProxyHosts ("ftp.nonProxyHosts");
1372 OUString sHttpProxyHost("http.proxyHost");
1373 OUString sHttpProxyPort("http.proxyPort");
1374 OUString sHttpNonProxyHosts("http.nonProxyHosts");
1376 // create Java Properties as JNI strings
1377 jstring jsFtpProxyHost= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpProxyHost.getStr()), sFtpProxyHost.getLength());
1378 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1379 jstring jsFtpProxyPort= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpProxyPort.getStr()), sFtpProxyPort.getLength());
1380 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1381 jstring jsFtpNonProxyHosts= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sFtpNonProxyHosts.getStr()), sFtpNonProxyHosts.getLength());
1382 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1383 jstring jsHttpProxyHost= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyHost.getStr()), sHttpProxyHost.getLength());
1384 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1385 jstring jsHttpProxyPort= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyPort.getStr()), sHttpProxyPort.getLength());
1386 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1387 jstring jsHttpNonProxyHosts= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpNonProxyHosts.getStr()), sHttpNonProxyHosts.getLength());
1388 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1390 // prepare java.lang.System.setProperty
1391 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1392 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/lang/System", nullptr);
1393 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1394 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.setProperty", nullptr);
1396 // call java.lang.System.getProperties
1397 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1398 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetStaticMethodID java.lang.System.getProperties", nullptr);
1399 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1400 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.getProperties", nullptr);
1401 // prepare java.util.Properties.remove
1402 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1403 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:FindClass java/util/Properties", nullptr);
1405 if (set_reset)
1407 // Set all network properties with the VM
1408 JVM jvm;
1409 getINetPropsFromConfig( &jvm, m_xContext->getServiceManager(), m_xContext);
1410 const ::std::vector< OUString> & Props = jvm.getProperties();
1411 typedef ::std::vector< OUString >::const_iterator C_IT;
1413 for( C_IT i= Props.begin(); i != Props.end(); ++i)
1415 OUString prop= *i;
1416 sal_Int32 index= prop.indexOf( '=');
1417 OUString propName= prop.copy( 0, index);
1418 OUString propValue= prop.copy( index + 1);
1420 if( propName.equals( sFtpProxyHost))
1422 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1423 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1424 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyHost, jsVal);
1425 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1427 else if( propName.equals( sFtpProxyPort))
1429 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1430 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1431 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyPort, jsVal);
1432 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1434 else if( propName.equals( sFtpNonProxyHosts))
1436 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1437 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1438 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpNonProxyHosts, jsVal);
1439 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1441 else if( propName.equals( sHttpProxyHost))
1443 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1444 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1445 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyHost, jsVal);
1446 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1448 else if( propName.equals( sHttpProxyPort))
1450 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1451 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1452 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyPort, jsVal);
1453 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1455 else if( propName.equals( sHttpNonProxyHosts))
1457 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1458 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:NewString", nullptr);
1459 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpNonProxyHosts, jsVal);
1460 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:CallStaticObjectMethod java.lang.System.setProperty", nullptr);
1464 else
1466 // call java.util.Properties.remove
1467 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1468 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException("JNI:GetMethodID java.util.Property.remove", nullptr);
1469 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyHost);
1470 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyPort);
1471 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpNonProxyHosts);
1472 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyHost);
1473 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyPort);
1474 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpNonProxyHosts);
1478 catch (css::uno::RuntimeException &)
1480 OSL_FAIL("RuntimeException");
1482 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1484 OSL_FAIL("jvmaccess::VirtualMachine::AttachGuard::CreationException");
1488 void JavaVirtualMachine::setUpUnoVirtualMachine(JNIEnv * environment) {
1489 css::uno::Reference< css::util::XMacroExpander > exp = css::util::theMacroExpander::get(m_xContext);
1490 OUString baseUrl;
1491 try {
1492 baseUrl = exp->expandMacros("$URE_INTERNAL_JAVA_DIR/");
1493 } catch (css::lang::IllegalArgumentException &) {
1494 throw css::uno::RuntimeException(
1495 "css::lang::IllegalArgumentException",
1496 static_cast< cppu::OWeakObject * >(this));
1498 OUString classPath;
1499 try {
1500 classPath = exp->expandMacros("$URE_INTERNAL_JAVA_CLASSPATH");
1501 } catch (css::lang::IllegalArgumentException &) {}
1502 jclass class_URLClassLoader = environment->FindClass(
1503 "java/net/URLClassLoader");
1504 if (class_URLClassLoader == nullptr) {
1505 handleJniException(environment);
1507 jmethodID ctor_URLClassLoader = environment->GetMethodID(
1508 class_URLClassLoader, "<init>", "([Ljava/net/URL;)V");
1509 if (ctor_URLClassLoader == nullptr) {
1510 handleJniException(environment);
1512 jclass class_URL = environment->FindClass("java/net/URL");
1513 if (class_URL == nullptr) {
1514 handleJniException(environment);
1516 jmethodID ctor_URL_1 = environment->GetMethodID(
1517 class_URL, "<init>", "(Ljava/lang/String;)V");
1518 if (ctor_URL_1 == nullptr) {
1519 handleJniException(environment);
1521 jvalue args[3];
1522 args[0].l = environment->NewString(
1523 reinterpret_cast< jchar const * >(baseUrl.getStr()),
1524 static_cast< jsize >(baseUrl.getLength()));
1525 if (args[0].l == nullptr) {
1526 handleJniException(environment);
1528 jobject base = environment->NewObjectA(class_URL, ctor_URL_1, args);
1529 if (base == nullptr) {
1530 handleJniException(environment);
1532 jmethodID ctor_URL_2 = environment->GetMethodID(
1533 class_URL, "<init>", "(Ljava/net/URL;Ljava/lang/String;)V");
1534 if (ctor_URL_2 == nullptr) {
1535 handleJniException(environment);
1537 jobjectArray classpath = jvmaccess::ClassPath::translateToUrls(
1538 m_xContext, environment, classPath);
1539 if (classpath == nullptr) {
1540 handleJniException(environment);
1542 args[0].l = base;
1543 args[1].l = environment->NewStringUTF("unoloader.jar");
1544 if (args[1].l == nullptr) {
1545 handleJniException(environment);
1547 args[0].l = environment->NewObjectA(class_URL, ctor_URL_2, args);
1548 if (args[0].l == nullptr) {
1549 handleJniException(environment);
1551 args[0].l = environment->NewObjectArray(1, class_URL, args[0].l);
1552 if (args[0].l == nullptr) {
1553 handleJniException(environment);
1555 jobject cl1 = environment->NewObjectA(
1556 class_URLClassLoader, ctor_URLClassLoader, args);
1557 if (cl1 == nullptr) {
1558 handleJniException(environment);
1560 jmethodID method_loadClass = environment->GetMethodID(
1561 class_URLClassLoader, "loadClass",
1562 "(Ljava/lang/String;)Ljava/lang/Class;");
1563 if (method_loadClass == nullptr) {
1564 handleJniException(environment);
1566 args[0].l = environment->NewStringUTF(
1567 "com.sun.star.lib.unoloader.UnoClassLoader");
1568 if (args[0].l == nullptr) {
1569 handleJniException(environment);
1571 jclass class_UnoClassLoader = static_cast< jclass >(
1572 environment->CallObjectMethodA(cl1, method_loadClass, args));
1573 if (class_UnoClassLoader == nullptr) {
1574 handleJniException(environment);
1576 jmethodID ctor_UnoClassLoader = environment->GetMethodID(
1577 class_UnoClassLoader, "<init>",
1578 "(Ljava/net/URL;[Ljava/net/URL;Ljava/lang/ClassLoader;)V");
1579 if (ctor_UnoClassLoader == nullptr) {
1580 handleJniException(environment);
1582 args[0].l = base;
1583 args[1].l = classpath;
1584 args[2].l = cl1;
1585 jobject cl2 = environment->NewObjectA(
1586 class_UnoClassLoader, ctor_UnoClassLoader, args);
1587 if (cl2 == nullptr) {
1588 handleJniException(environment);
1590 try {
1591 m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(
1592 m_xVirtualMachine, cl2);
1593 } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
1594 throw css::uno::RuntimeException(
1595 "jvmaccess::UnoVirtualMachine::CreationException",
1596 static_cast< cppu::OWeakObject * >(this));
1600 void JavaVirtualMachine::handleJniException(JNIEnv * environment) {
1601 environment->ExceptionClear();
1602 throw css::uno::RuntimeException(
1603 "JNI exception occurred",
1604 static_cast< cppu::OWeakObject * >(this));
1607 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */