tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / stoc / source / javavm / javavm.cxx
blob2d10d3f3876a6559e7ffce4fc678165144a6b45e
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/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>
49 #include <comphelper/propertysequence.hxx>
50 #include <comphelper/SetFlagContextHelper.hxx>
51 #include <cppuhelper/exc_hlp.hxx>
52 #include <cppuhelper/supportsservice.hxx>
53 #include <cppuhelper/weak.hxx>
54 #include <jvmaccess/classpath.hxx>
55 #include <jvmaccess/unovirtualmachine.hxx>
56 #include <jvmaccess/virtualmachine.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>
63 #include <i18nlangtag/languagetag.hxx>
64 #include <jni.h>
66 #include <stack>
67 #include <string.h>
68 #include <time.h>
69 #include <memory>
70 #include <utility>
71 #include <vector>
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
82 #ifdef MACOSX
83 #include <premac.h>
84 #include <CoreFoundation/CoreFoundation.h>
85 #include <postmac.h>
86 #endif
88 /* Within this implementation of the com.sun.star.java.JavaVirtualMachine
89 * service and com.sun.star.java.theJavaVirtualMachine singleton, the method
90 * com.sun.star.java.XJavaVM.getJavaVM relies on the following:
91 * 1 The string "$URE_INTERNAL_JAVA_DIR/" is expanded via the
92 * com.sun.star.util.theMacroExpander singleton into an internal (see the
93 * com.sun.star.uri.ExternalUriReferenceTranslator service), hierarchical URI
94 * reference relative to which the URE JAR files can be addressed.
95 * 2 The string "$URE_INTERNAL_JAVA_CLASSPATH" is either not expandable via the
96 * com.sun.star.util.theMacroExpander singleton
97 * (com.sun.star.lang.IllegalArgumentException), or is expanded via the
98 * com.sun.star.util.theMacroExpander singleton into a list of zero or more
99 * internal (see the com.sun.star.uri.ExternalUriReferenceTranslator service)
100 * URIs, where any space characters (U+0020) are ignored (and, in particular,
101 * separate adjacent URIs).
102 * If either of these requirements is not met, getJavaVM raises a
103 * com.sun.star.uno.RuntimeException.
106 using stoc_javavm::JavaVirtualMachine;
108 namespace {
111 class NoJavaIniException: public css::uno::Exception
115 typedef std::stack< jvmaccess::VirtualMachine::AttachGuard * > GuardStack;
117 extern "C" {
119 static void destroyAttachGuards(void * pData)
121 GuardStack * pStack = static_cast< GuardStack * >(pData);
122 if (pStack != nullptr)
124 while (!pStack->empty())
126 delete pStack->top();
127 pStack->pop();
129 delete pStack;
135 bool askForRetry(css::uno::Any const & rException)
137 if (comphelper::IsContextFlagActive(u"DontEnableJava"_ustr))
138 return false;
140 css::uno::Reference< css::uno::XCurrentContext > xContext(
141 css::uno::getCurrentContext());
142 if (xContext.is())
144 css::uno::Reference< css::task::XInteractionHandler > xHandler;
145 xContext->getValueByName(u"java-vm.interaction-handler"_ustr)
146 >>= xHandler;
147 if (xHandler.is())
149 rtl::Reference< stoc_javavm::InteractionRequest > xRequest(
150 new stoc_javavm::InteractionRequest(rException));
151 xHandler->handle(xRequest);
152 return xRequest->retry();
155 return false;
158 // Only gets the properties if the "Proxy Server" entry in the option dialog is
159 // set to manual (i.e. not to none)
160 /// @throws css::uno::Exception
161 void getINetPropsFromConfig(stoc_javavm::JVM * pjvm,
162 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
163 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
165 css::uno::Reference<css::uno::XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
166 u"com.sun.star.configuration.ConfigurationRegistry"_ustr,
167 xCtx );
168 if(!xConfRegistry.is()) throw css::uno::RuntimeException(u"javavm.cxx: couldn't get ConfigurationRegistry"_ustr, nullptr);
170 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(xConfRegistry, css::uno::UNO_QUERY_THROW);
171 xConfRegistry_simple->open(u"org.openoffice.Inet"_ustr, true, false);
172 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
174 // if ooInetProxyType is not 0 then read the settings
175 css::uno::Reference<css::registry::XRegistryKey> proxyEnable= xRegistryRootKey->openKey(u"Settings/ooInetProxyType"_ustr);
176 if( proxyEnable.is() && 0 != proxyEnable->getLongValue())
178 // read http proxy name
179 css::uno::Reference<css::registry::XRegistryKey> httpProxy_name = xRegistryRootKey->openKey(u"Settings/ooInetHTTPProxyName"_ustr);
180 if(httpProxy_name.is() && !httpProxy_name->getStringValue().isEmpty()) {
181 OUString httpHost = "http.proxyHost=" + httpProxy_name->getStringValue();
183 // read http proxy port
184 css::uno::Reference<css::registry::XRegistryKey> httpProxy_port = xRegistryRootKey->openKey(u"Settings/ooInetHTTPProxyPort"_ustr);
185 if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
186 OUString httpPort = "http.proxyPort=" + OUString::number(httpProxy_port->getLongValue());
188 pjvm->pushProp(httpHost);
189 pjvm->pushProp(httpPort);
193 // read https proxy name
194 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_name = xRegistryRootKey->openKey(u"Settings/ooInetHTTPSProxyName"_ustr);
195 if(httpsProxy_name.is() && !httpsProxy_name->getStringValue().isEmpty()) {
196 OUString httpsHost = "https.proxyHost=" + httpsProxy_name->getStringValue();
198 // read https proxy port
199 css::uno::Reference<css::registry::XRegistryKey> httpsProxy_port = xRegistryRootKey->openKey(u"Settings/ooInetHTTPSProxyPort"_ustr);
200 if(httpsProxy_port.is() && httpsProxy_port->getLongValue()) {
201 OUString httpsPort = "https.proxyPort=" + OUString::number(httpsProxy_port->getLongValue());
203 pjvm->pushProp(httpsHost);
204 pjvm->pushProp(httpsPort);
208 // read nonProxyHosts
209 css::uno::Reference<css::registry::XRegistryKey> nonProxies_name = xRegistryRootKey->openKey(u"Settings/ooInetNoProxy"_ustr);
210 if(nonProxies_name.is() && !nonProxies_name->getStringValue().isEmpty()) {
211 OUString value = nonProxies_name->getStringValue();
212 // replace the separator ";" by "|"
213 value = value.replace(';', '|');
215 OUString httpNonProxyHosts = "http.nonProxyHosts=" + value;
217 pjvm->pushProp(httpNonProxyHosts);
220 xConfRegistry_simple->close();
223 /// @throws css::uno::Exception
224 void getDefaultLocaleFromConfig(
225 stoc_javavm::JVM * pjvm,
226 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
227 const css::uno::Reference<css::uno::XComponentContext> &xCtx )
229 css::uno::Reference<css::uno::XInterface> xConfRegistry =
230 xSMgr->createInstanceWithContext( u"com.sun.star.configuration.ConfigurationRegistry"_ustr, xCtx );
231 if(!xConfRegistry.is())
232 throw css::uno::RuntimeException(
233 u"javavm.cxx: couldn't get ConfigurationRegistry"_ustr, nullptr);
235 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
236 xConfRegistry, css::uno::UNO_QUERY_THROW);
237 xConfRegistry_simple->open(u"org.openoffice.Setup"_ustr, true, false);
238 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
240 // Since 1.7 Java knows DISPLAY and FORMAT locales, which match our UI and
241 // system locale. See
242 // http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/file/569b1b644416/src/share/classes/java/util/Locale.java
243 // https://docs.oracle.com/javase/tutorial/i18n/locale/scope.html
244 // https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html
246 // Read UI language/locale.
247 css::uno::Reference<css::registry::XRegistryKey> xUILocale = xRegistryRootKey->openKey(u"L10N/ooLocale"_ustr);
248 if(xUILocale.is() && !xUILocale->getStringValue().isEmpty()) {
249 LanguageTag aLanguageTag( xUILocale->getStringValue());
250 OUString language;
251 OUString script;
252 OUString country;
253 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
254 // Locale.forLanguageTag() are used, or non-standardized variant field
255 // content which we ignore.
256 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
258 if(!language.isEmpty()) {
259 OUString prop = "user.language=" + language;
260 pjvm->pushProp(prop);
263 // As of Java 7 also script is supported.
264 if(!script.isEmpty()) {
265 OUString prop = "user.script=" + script;
266 pjvm->pushProp(prop);
269 if(!country.isEmpty()) {
270 OUString prop = "user.country=" + country;
271 pjvm->pushProp(prop);
274 // Java 7 DISPLAY category is our UI language/locale.
275 if(!language.isEmpty()) {
276 OUString prop = "user.language.display=" + language;
277 pjvm->pushProp(prop);
280 if(!script.isEmpty()) {
281 OUString prop = "user.script.display=" + script;
282 pjvm->pushProp(prop);
285 if(!country.isEmpty()) {
286 OUString prop = "user.country.display=" + country;
287 pjvm->pushProp(prop);
291 // Read system locale.
292 css::uno::Reference<css::registry::XRegistryKey> xLocale = xRegistryRootKey->openKey(u"L10N/ooSetupSystemLocale"_ustr);
293 if(xLocale.is() && !xLocale->getStringValue().isEmpty()) {
294 LanguageTag aLanguageTag( xLocale->getStringValue());
295 OUString language;
296 OUString script;
297 OUString country;
298 // Java knows nothing but plain old ISO codes, unless Locale.Builder or
299 // Locale.forLanguageTag() are used, or non-standardized variant field
300 // content which we ignore.
301 aLanguageTag.getIsoLanguageScriptCountry( language, script, country);
303 // Java 7 FORMAT category is our system locale.
304 if(!language.isEmpty()) {
305 OUString prop = "user.language.format=" + language;
306 pjvm->pushProp(prop);
309 if(!script.isEmpty()) {
310 OUString prop = "user.script.format=" + script;
311 pjvm->pushProp(prop);
314 if(!country.isEmpty()) {
315 OUString prop = "user.country.format=" + country;
316 pjvm->pushProp(prop);
320 xConfRegistry_simple->close();
323 /// @throws css::uno::Exception
324 void getJavaPropsFromSafetySettings(
325 stoc_javavm::JVM * pjvm,
326 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
327 const css::uno::Reference<css::uno::XComponentContext> &xCtx)
329 css::uno::Reference<css::uno::XInterface> xConfRegistry =
330 xSMgr->createInstanceWithContext(
331 u"com.sun.star.configuration.ConfigurationRegistry"_ustr,
332 xCtx);
333 if(!xConfRegistry.is())
334 throw css::uno::RuntimeException(
335 u"javavm.cxx: couldn't get ConfigurationRegistry"_ustr, nullptr);
337 css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
338 xConfRegistry, css::uno::UNO_QUERY_THROW);
339 xConfRegistry_simple->open(
340 u"org.openoffice.Office.Java"_ustr,
341 true, false);
342 css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey =
343 xConfRegistry_simple->getRootKey();
345 if (xRegistryRootKey.is())
347 css::uno::Reference<css::registry::XRegistryKey> key_NetAccess= xRegistryRootKey->openKey(u"VirtualMachine/NetAccess"_ustr);
348 if (key_NetAccess.is())
350 sal_Int32 val= key_NetAccess->getLongValue();
351 OUString sVal;
352 switch( val)
354 case 0: sVal = "host";
355 break;
356 case 1: sVal = "unrestricted";
357 break;
358 case 3: sVal = "none";
359 break;
361 OUString sProperty = "appletviewer.security.mode=" + sVal;
362 pjvm->pushProp(sProperty);
364 css::uno::Reference<css::registry::XRegistryKey> key_CheckSecurity= xRegistryRootKey->openKey(
365 u"VirtualMachine/Security"_ustr);
366 if( key_CheckSecurity.is())
368 bool val = static_cast<bool>(key_CheckSecurity->getLongValue());
369 OUString sProperty(u"stardiv.security.disableSecurity="_ustr);
370 if( val)
371 sProperty += "false";
372 else
373 sProperty += "true";
374 pjvm->pushProp( sProperty);
377 xConfRegistry_simple->close();
380 void setTimeZone(stoc_javavm::JVM * pjvm) noexcept {
381 /* A Bug in the Java function
382 ** struct Hjava_util_Properties * java_lang_System_initProperties(
383 ** struct Hjava_lang_System *this,
384 ** struct Hjava_util_Properties *props);
385 ** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
387 struct tm *tmData;
388 time_t clock = time(nullptr);
389 tzset();
390 tmData = localtime(&clock);
391 #ifdef MACOSX
392 char * p = tmData->tm_zone;
393 #elif defined(_MSC_VER)
394 char * p = _tzname[0];
395 (void)tmData;
396 #else
397 char * p = tzname[0];
398 (void)tmData;
399 #endif
401 if (!strcmp(TIMEZONE, p))
402 pjvm->pushProp(u"user.timezone=ECT"_ustr);
405 /// @throws css::uno::Exception
406 void initVMConfiguration(
407 stoc_javavm::JVM * pjvm,
408 const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
409 const css::uno::Reference<css::uno::XComponentContext > &xCtx)
411 stoc_javavm::JVM jvm;
412 try {
413 getINetPropsFromConfig(&jvm, xSMgr, xCtx);
415 catch(const css::uno::Exception & exception) {
416 SAL_INFO("stoc", "can not get INETProps because of " << exception);
419 try {
420 getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
422 catch(const css::uno::Exception & exception) {
423 SAL_INFO("stoc", "can not get locale because of " << exception);
428 getJavaPropsFromSafetySettings(&jvm, xSMgr, xCtx);
430 catch(const css::uno::Exception & exception) {
431 SAL_INFO("stoc", "couldn't get safety settings because of " << exception);
434 *pjvm = std::move(jvm);
436 // rhbz#1285356, native look will be gtk2, which crashes
437 // when gtk3 is already loaded. Until there is a solution
438 // java-side force look and feel to something that doesn't
439 // crash when we are using gtk3
440 if (getenv("STOC_FORCE_SYSTEM_LAF"))
441 pjvm->pushProp(u"swing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel"_ustr);
443 setTimeZone(pjvm);
446 class DetachCurrentThread {
447 public:
448 explicit DetachCurrentThread(JavaVM * jvm): m_jvm(jvm) {}
450 ~DetachCurrentThread() {
451 #ifdef MACOSX
452 // tdf#101376 don't detach thread if it is the main thread on macOS
453 // On macOS, many AWT classes do their work on the main thread
454 // deep in native methods in the java.awt.* classes. The problem
455 // is that Oracle's and OpenJDK's JVMs don't bracket their
456 // "perform on main thread" native calls with "attach/detach
457 // current thread" calls to the JVM.
458 if (CFRunLoopGetCurrent() != CFRunLoopGetMain())
459 #endif
460 if (m_jvm->DetachCurrentThread() != 0) {
461 OSL_ASSERT(false);
465 DetachCurrentThread(const DetachCurrentThread&) = delete;
466 DetachCurrentThread& operator=(const DetachCurrentThread&) = delete;
468 private:
469 JavaVM * m_jvm;
474 JavaVirtualMachine::JavaVirtualMachine(
475 css::uno::Reference< css::uno::XComponentContext > xContext):
476 WeakComponentImplHelper(m_aMutex),
477 m_xContext(std::move(xContext)),
478 m_bDisposed(false),
479 m_pJavaVm(nullptr),
480 m_aAttachGuards(destroyAttachGuards) // TODO check for validity
483 void SAL_CALL
484 JavaVirtualMachine::initialize(css::uno::Sequence< css::uno::Any > const &
485 rArguments)
487 osl::MutexGuard aGuard(m_aMutex);
488 if (m_bDisposed)
489 throw css::lang::DisposedException(
490 u""_ustr, getXWeak());
491 if (m_xUnoVirtualMachine.is())
492 throw css::uno::RuntimeException(
493 u"bad call to initialize"_ustr,
494 getXWeak());
495 css::beans::NamedValue val;
496 if (rArguments.getLength() == 1 && (rArguments[0] >>= val) && val.Name == "UnoVirtualMachine" )
498 OSL_ENSURE(
499 sizeof (sal_Int64) >= sizeof (jvmaccess::UnoVirtualMachine *),
500 "Pointer cannot be represented as sal_Int64");
501 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
502 static_cast< jvmaccess::UnoVirtualMachine * >(nullptr));
503 val.Value >>= nPointer;
504 m_xUnoVirtualMachine =
505 reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer);
506 } else {
507 OSL_ENSURE(
508 sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *),
509 "Pointer cannot be represented as sal_Int64");
510 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
511 static_cast< jvmaccess::VirtualMachine * >(nullptr));
512 if (rArguments.getLength() == 1)
513 rArguments[0] >>= nPointer;
514 rtl::Reference< jvmaccess::VirtualMachine > vm(
515 reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer));
516 if (vm.is()) {
517 try {
518 m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(vm, nullptr);
519 } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
520 css::uno::Any anyEx = cppu::getCaughtException();
521 throw css::lang::WrappedTargetRuntimeException(
522 u"jvmaccess::UnoVirtualMachine::CreationException"_ustr,
523 getXWeak(), anyEx );
527 if (!m_xUnoVirtualMachine.is()) {
528 throw css::lang::IllegalArgumentException(
529 u"sequence of exactly one any containing either (a) a"
530 " com.sun.star.beans.NamedValue with Name"
531 " \"UnoVirtualMachine\" and Value a hyper representing a"
532 " non-null pointer to a jvmaccess:UnoVirtualMachine, or (b)"
533 " a hyper representing a non-null pointer to a"
534 " jvmaccess::VirtualMachine required"_ustr,
535 getXWeak(), 0);
537 m_xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
540 OUString SAL_CALL JavaVirtualMachine::getImplementationName()
542 return u"com.sun.star.comp.stoc.JavaVirtualMachine"_ustr;
545 sal_Bool SAL_CALL
546 JavaVirtualMachine::supportsService(OUString const & rServiceName)
548 return cppu::supportsService(this, rServiceName);
551 css::uno::Sequence< OUString > SAL_CALL
552 JavaVirtualMachine::getSupportedServiceNames()
554 return { u"com.sun.star.java.JavaVirtualMachine"_ustr };
557 css::uno::Any SAL_CALL
558 JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
560 osl::MutexGuard aGuard(m_aMutex);
561 if (m_bDisposed)
562 throw css::lang::DisposedException(
563 u""_ustr, getXWeak());
564 css::uno::Sequence< sal_Int8 > aId(16);
565 rtl_getGlobalProcessId(reinterpret_cast< sal_uInt8 * >(aId.getArray()));
566 enum ReturnType {
567 RETURN_JAVAVM, RETURN_VIRTUALMACHINE, RETURN_UNOVIRTUALMACHINE };
568 ReturnType returnType =
569 rProcessId.getLength() == 17 && rProcessId[16] == 0
570 ? RETURN_VIRTUALMACHINE
571 : rProcessId.getLength() == 17 && rProcessId[16] == 1
572 ? RETURN_UNOVIRTUALMACHINE
573 : RETURN_JAVAVM;
574 css::uno::Sequence< sal_Int8 > aProcessId(rProcessId);
575 if (returnType != RETURN_JAVAVM)
576 aProcessId.realloc(16);
577 if (aId != aProcessId)
578 return css::uno::Any();
580 std::unique_ptr<JavaInfo> info;
581 while (!m_xVirtualMachine.is()) // retry until successful
583 stoc_javavm::JVM aJvm;
584 initVMConfiguration(&aJvm, m_xContext->getServiceManager(),
585 m_xContext);
586 const std::vector<OUString> & props = aJvm.getProperties();
587 std::vector<OUString> options;
588 options.reserve(props.size());
589 for (auto const& i : props)
591 options.push_back(i.startsWith("-") ? i : "-D" + i);
594 JNIEnv * pMainThreadEnv = nullptr;
595 javaFrameworkError errcode;
597 if (getenv("STOC_FORCE_NO_JRE"))
598 errcode = JFW_E_NO_SELECT;
599 else
600 errcode = jfw_startVM(info.get(), options, & m_pJavaVm,
601 & pMainThreadEnv);
603 bool bStarted = false;
604 switch (errcode)
606 case JFW_E_NONE: bStarted = true; break;
607 case JFW_E_NO_SELECT:
609 // No Java configured. We silently run the Java configuration
610 info.reset();
611 javaFrameworkError errFind;
612 if (getenv("STOC_FORCE_NO_JRE"))
613 errFind = JFW_E_NO_JAVA_FOUND;
614 else
615 errFind = jfw_findAndSelectJRE(&info);
616 if (errFind == JFW_E_NONE)
618 continue;
620 else if (errFind == JFW_E_NO_JAVA_FOUND)
623 //Warning MessageBox:
624 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task.
625 //Please install a JRE and restart %PRODUCTNAME.
626 css::java::JavaNotFoundException exc(
627 u"JavaVirtualMachine::getJavaVM failed because"
628 " No suitable JRE found!"_ustr,
629 getXWeak());
630 askForRetry(css::uno::Any(exc));
631 return css::uno::Any();
633 else
635 //An unexpected error occurred
636 throw css::uno::RuntimeException(
637 "[JavaVirtualMachine]:An unexpected error occurred"
638 " while searching for a Java, " + OUString::number(errFind), nullptr);
641 case JFW_E_INVALID_SETTINGS:
643 //Warning MessageBox:
644 // The %PRODUCTNAME configuration has been changed. Under Tools
645 // - Options - %PRODUCTNAME - Java, select the Java runtime environment
646 // you want to have used by %PRODUCTNAME.
647 css::java::InvalidJavaSettingsException exc(
648 u"JavaVirtualMachine::getJavaVM failed because"
649 " Java settings have changed!"_ustr,
650 getXWeak());
651 askForRetry(css::uno::Any(exc));
652 return css::uno::Any();
654 case JFW_E_JAVA_DISABLED:
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 u"JavaVirtualMachine::getJavaVM failed because Java is disabled!"_ustr,
662 getXWeak());
663 if( ! askForRetry(css::uno::Any(exc)))
664 return css::uno::Any();
665 continue;
667 case JFW_E_VM_CREATION_FAILED:
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))
676 bool bExist = false;
677 if (JFW_E_NONE == jfw_existJRE(aJavaInfo.get(), &bExist))
679 if (!bExist
680 && ! (aJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
682 info.reset();
683 javaFrameworkError errFind = jfw_findAndSelectJRE(
684 &info);
685 if (errFind == JFW_E_NONE)
687 continue;
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 u"JavaVirtualMachine::getJavaVM failed because Java is defective!"_ustr,
699 getXWeak(), 0);
700 askForRetry(css::uno::Any(exc));
701 return css::uno::Any();
703 case JFW_E_RUNNING_JVM:
705 //This service should make sure that we do not start java twice.
706 OSL_ASSERT(false);
707 break;
709 case JFW_E_NEED_RESTART:
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 u"JavaVirtualMachine::getJavaVM failed because "
716 "Office must be restarted before Java can be used!"_ustr,
717 getXWeak());
718 askForRetry(css::uno::Any(exc));
719 return css::uno::Any();
721 default:
722 //RuntimeException: error is somewhere in the java framework.
723 //An unexpected error occurred
724 throw css::uno::RuntimeException(
725 u"[JavaVirtualMachine]:An unexpected error occurred"
726 " while starting Java!"_ustr, nullptr);
729 if (bStarted)
732 DetachCurrentThread detach(m_pJavaVm);
733 // necessary to make debugging work; this thread will be
734 // suspended when the destructor of detach returns
735 m_xVirtualMachine = new jvmaccess::VirtualMachine(
736 m_pJavaVm, JNI_VERSION_1_2, true, pMainThreadEnv);
737 setUpUnoVirtualMachine(pMainThreadEnv);
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
742 registerConfigChangesListener();
744 break;
747 if (!m_xUnoVirtualMachine.is()) {
748 try {
749 jvmaccess::VirtualMachine::AttachGuard guard(m_xVirtualMachine);
750 setUpUnoVirtualMachine(guard.getEnvironment());
751 } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
752 css::uno::Any anyEx = cppu::getCaughtException();
753 throw css::lang::WrappedTargetRuntimeException(
754 u"jvmaccess::VirtualMachine::AttachGuard::CreationException occurred"_ustr,
755 getXWeak(), anyEx );
758 switch (returnType) {
759 default: // RETURN_JAVAVM
760 if (m_pJavaVm == nullptr) {
761 throw css::uno::RuntimeException(
762 u"JavaVirtualMachine service was initialized in a way"
763 " that the requested JavaVM pointer is not available"_ustr,
764 getXWeak());
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()));
779 sal_Bool SAL_CALL JavaVirtualMachine::isVMStarted()
781 osl::MutexGuard aGuard(m_aMutex);
782 if (m_bDisposed)
783 throw css::lang::DisposedException(
784 OUString(), getXWeak());
785 return m_xUnoVirtualMachine.is();
788 sal_Bool SAL_CALL JavaVirtualMachine::isVMEnabled()
791 osl::MutexGuard aGuard(m_aMutex);
792 if (m_bDisposed)
793 throw css::lang::DisposedException(
794 OUString(), getXWeak());
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;
806 sal_Bool SAL_CALL JavaVirtualMachine::isThreadAttached()
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();
819 void SAL_CALL JavaVirtualMachine::registerThread()
821 osl::MutexGuard aGuard(m_aMutex);
822 if (m_bDisposed)
823 throw css::lang::DisposedException(
824 u""_ustr, getXWeak());
825 if (!m_xUnoVirtualMachine.is())
826 throw css::uno::RuntimeException(
827 u"JavaVirtualMachine::registerThread: null VirtualMachine"_ustr,
828 getXWeak());
829 GuardStack * pStack
830 = static_cast< GuardStack * >(m_aAttachGuards.getData());
831 if (pStack == nullptr)
833 pStack = new GuardStack;
834 m_aAttachGuards.setData(pStack);
838 pStack->push(
839 new jvmaccess::VirtualMachine::AttachGuard(
840 m_xUnoVirtualMachine->getVirtualMachine()));
842 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
844 css::uno::Any anyEx = cppu::getCaughtException();
845 throw css::lang::WrappedTargetRuntimeException(
846 u"JavaVirtualMachine::registerThread: jvmaccess::"
847 "VirtualMachine::AttachGuard::CreationException"_ustr,
848 getXWeak(), anyEx );
852 void SAL_CALL JavaVirtualMachine::revokeThread()
854 osl::MutexGuard aGuard(m_aMutex);
855 if (m_bDisposed)
856 throw css::lang::DisposedException(
857 u""_ustr, getXWeak());
858 if (!m_xUnoVirtualMachine.is())
859 throw css::uno::RuntimeException(
860 u"JavaVirtualMachine::revokeThread: null VirtualMachine"_ustr,
861 getXWeak());
862 GuardStack * pStack
863 = static_cast< GuardStack * >(m_aAttachGuards.getData());
864 if (pStack == nullptr || pStack->empty())
865 throw css::uno::RuntimeException(
866 u"JavaVirtualMachine::revokeThread: no matching registerThread"_ustr,
867 getXWeak());
868 delete pStack->top();
869 pStack->pop();
872 void SAL_CALL
873 JavaVirtualMachine::disposing(css::lang::EventObject const & rSource)
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();
882 void SAL_CALL JavaVirtualMachine::elementInserted(
883 css::container::ContainerEvent const &)
886 void SAL_CALL JavaVirtualMachine::elementRemoved(
887 css::container::ContainerEvent const &)
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.
895 void SAL_CALL JavaVirtualMachine::elementReplaced(
896 css::container::ContainerEvent const & rEvent)
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.
904 OUString aAccessor;
905 rEvent.Accessor >>= aAccessor;
906 OUString aPropertyName;
907 OUString aPropertyValue;
908 bool bSecurityChanged = false;
909 if ( aAccessor == "ooInetProxyType" )
911 // Proxy none, manually
912 sal_Int32 value = 0;
913 rEvent.Element >>= value;
914 setINetSettingsInVM(value != 0);
915 return;
917 else if ( aAccessor == "ooInetHTTPProxyName" )
919 aPropertyName = "http.proxyHost";
920 rEvent.Element >>= aPropertyValue;
922 else if ( aAccessor == "ooInetHTTPProxyPort" )
924 aPropertyName = "http.proxyPort";
925 sal_Int32 n = 0;
926 rEvent.Element >>= n;
927 aPropertyValue = OUString::number(n);
929 else if ( aAccessor == "ooInetHTTPSProxyName" )
931 aPropertyName = "https.proxyHost";
932 rEvent.Element >>= aPropertyValue;
934 else if ( aAccessor == "ooInetHTTPSProxyPort" )
936 aPropertyName = "https.proxyPort";
937 sal_Int32 n = 0;
938 rEvent.Element >>= n;
939 aPropertyValue = OUString::number(n);
941 else if ( aAccessor == "ooInetNoProxy" )
943 aPropertyName = "http.nonProxyHosts";
944 rEvent.Element >>= aPropertyValue;
945 aPropertyValue = aPropertyValue.replace(';', '|');
947 else if ( aAccessor == "NetAccess" )
949 aPropertyName = "appletviewer.security.mode";
950 sal_Int32 n = 0;
951 if (rEvent.Element >>= n)
952 switch (n)
954 case 0:
955 aPropertyValue = "host";
956 break;
957 case 1:
958 aPropertyValue = "unrestricted";
959 break;
960 case 3:
961 aPropertyValue = "none";
962 break;
964 else
965 return;
966 bSecurityChanged = true;
968 else if ( aAccessor == "Security" )
970 aPropertyName = "stardiv.security.disableSecurity";
971 bool b;
972 if (rEvent.Element >>= b)
973 if (b)
974 aPropertyValue = "false";
975 else
976 aPropertyValue = "true";
977 else
978 return;
979 bSecurityChanged = true;
981 else
982 return;
984 rtl::Reference< jvmaccess::VirtualMachine > xVirtualMachine;
986 osl::MutexGuard aGuard(m_aMutex);
987 if (m_xUnoVirtualMachine.is()) {
988 xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
991 if (!xVirtualMachine.is())
992 return;
996 jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
997 xVirtualMachine);
998 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1000 // call java.lang.System.setProperty
1001 // String setProperty( String key, String value)
1002 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1003 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:FindClass java/lang/System"_ustr, nullptr);
1004 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1005 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetStaticMethodID java.lang.System.setProperty"_ustr, nullptr);
1007 jstring jsPropName= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyName.getStr()), aPropertyName.getLength());
1008 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1010 // remove the property if it does not have a value ( user left the dialog field empty)
1011 // or if the port is set to 0
1012 aPropertyValue= aPropertyValue.trim();
1013 if( aPropertyValue.isEmpty() ||
1014 ((aPropertyName == "http.proxyPort" /*|| aPropertyName == "socksProxyPort"*/) && aPropertyValue == "0")
1017 // call java.lang.System.getProperties
1018 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1019 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetStaticMethodID java.lang.System.getProperties"_ustr, nullptr);
1020 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1021 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.getProperties"_ustr, nullptr);
1022 // call java.util.Properties.remove
1023 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1024 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:FindClass java/util/Properties"_ustr, nullptr);
1025 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1026 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetMethodID java.util.Properties.remove"_ustr, nullptr);
1027 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName);
1029 else
1031 // Change the Value of the property
1032 jstring jsPropValue= pJNIEnv->NewString( reinterpret_cast<jchar const *>(aPropertyValue.getStr()), aPropertyValue.getLength());
1033 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1034 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName, jsPropValue);
1035 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.setProperty"_ustr, nullptr);
1038 // If the settings for Security and NetAccess changed then we have to notify the SandboxSecurity
1039 // SecurityManager
1040 // call System.getSecurityManager()
1041 if (bSecurityChanged)
1043 jmethodID jmGetSecur= pJNIEnv->GetStaticMethodID( jcSystem,"getSecurityManager","()Ljava/lang/SecurityManager;");
1044 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetStaticMethodID java.lang.System.getSecurityManager"_ustr, nullptr);
1045 jobject joSecur= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetSecur);
1046 if (joSecur != nullptr)
1048 // Make sure the SecurityManager is our SandboxSecurity
1049 // FindClass("com.sun.star.lib.sandbox.SandboxSecurityManager" only worked at the first time
1050 // this code was executed. Maybe it is a security feature. However, all attempts to debug the
1051 // SandboxSecurity class (maybe the VM invokes checkPackageAccess) failed.
1052 // jclass jcSandboxSec= pJNIEnv->FindClass("com.sun.star.lib.sandbox.SandboxSecurity");
1053 // if(pJNIEnv->ExceptionOccurred()) throw RuntimeException("JNI:FindClass com.sun.star.lib.sandbox.SandboxSecurity");
1054 // jboolean bIsSand= pJNIEnv->IsInstanceOf( joSecur, jcSandboxSec);
1055 // The SecurityManagers class Name must be com.sun.star.lib.sandbox.SandboxSecurity
1056 jclass jcSec= pJNIEnv->GetObjectClass( joSecur);
1057 jclass jcClass= pJNIEnv->FindClass("java/lang/Class");
1058 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:FindClass java.lang.Class"_ustr, nullptr);
1059 jmethodID jmName= pJNIEnv->GetMethodID( jcClass,"getName","()Ljava/lang/String;");
1060 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetMethodID java.lang.Class.getName"_ustr, nullptr);
1061 jstring jsClass= static_cast<jstring>(pJNIEnv->CallObjectMethod( jcSec, jmName));
1062 const jchar* jcharName= pJNIEnv->GetStringChars( jsClass, nullptr);
1063 OUString sName(reinterpret_cast<sal_Unicode const *>(jcharName));
1064 bool bIsSandbox;
1065 bIsSandbox = sName == "com.sun.star.lib.sandbox.SandboxSecurity";
1066 pJNIEnv->ReleaseStringChars( jsClass, jcharName);
1068 if (bIsSandbox)
1070 // call SandboxSecurity.reset
1071 jmethodID jmReset= pJNIEnv->GetMethodID( jcSec,"reset","()V");
1072 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetMethodID com.sun.star.lib.sandbox.SandboxSecurity.reset"_ustr, nullptr);
1073 pJNIEnv->CallVoidMethod( joSecur, jmReset);
1074 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallVoidMethod com.sun.star.lib.sandbox.SandboxSecurity.reset"_ustr, nullptr);
1079 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1081 css::uno::Any anyEx = cppu::getCaughtException();
1082 throw css::lang::WrappedTargetRuntimeException(
1083 u"jvmaccess::VirtualMachine::AttachGuard::CreationException"_ustr,
1084 getXWeak(), anyEx );
1088 JavaVirtualMachine::~JavaVirtualMachine()
1090 if (m_xInetConfiguration.is())
1091 // We should never get here, but just in case...
1094 m_xInetConfiguration->removeContainerListener(this);
1096 catch (css::uno::Exception &)
1098 OSL_FAIL("com.sun.star.uno.Exception caught");
1100 if (m_xJavaConfiguration.is())
1101 // We should never get here, but just in case...
1104 m_xJavaConfiguration->removeContainerListener(this);
1106 catch (css::uno::Exception &)
1108 OSL_FAIL("com.sun.star.uno.Exception caught");
1112 void SAL_CALL JavaVirtualMachine::disposing()
1114 css::uno::Reference< css::container::XContainer > xContainer1;
1115 css::uno::Reference< css::container::XContainer > xContainer2;
1117 osl::MutexGuard aGuard(m_aMutex);
1118 m_bDisposed = true;
1119 xContainer1 = m_xInetConfiguration;
1120 m_xInetConfiguration.clear();
1121 xContainer2 = m_xJavaConfiguration;
1122 m_xJavaConfiguration.clear();
1124 if (xContainer1.is())
1125 xContainer1->removeContainerListener(this);
1126 if (xContainer2.is())
1127 xContainer2->removeContainerListener(this);
1130 /*We listen to changes in the configuration. For example, the user changes the proxy
1131 settings in the options dialog (menu tools). Then we are notified of this change and
1132 if the java vm is already running we change the properties (System.lang.System.setProperties)
1133 through JNI.
1134 To receive notifications this class implements XContainerListener.
1136 void JavaVirtualMachine::registerConfigChangesListener()
1140 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
1141 m_xContext->getValueByName(
1142 u"/singletons/com.sun.star.configuration.theDefaultProvider"_ustr),
1143 css::uno::UNO_QUERY);
1145 if (xConfigProvider.is())
1147 // We register this instance as listener to changes in org.openoffice.Inet/Settings
1148 // arguments for ConfigurationAccess
1149 css::uno::Sequence<css::uno::Any> aArguments(comphelper::InitAnyPropertySequence(
1151 {"nodepath", css::uno::Any(u"org.openoffice.Inet/Settings"_ustr)},
1152 {"depth", css::uno::Any(sal_Int32(-1))}
1153 }));
1154 m_xInetConfiguration.set(
1155 xConfigProvider->createInstanceWithArguments(
1156 u"com.sun.star.configuration.ConfigurationAccess"_ustr,
1157 aArguments),
1158 css::uno::UNO_QUERY);
1160 if (m_xInetConfiguration.is())
1161 m_xInetConfiguration->addContainerListener(this);
1163 // now register as listener to changes in org.openoffice.Java/VirtualMachine
1164 css::uno::Sequence<css::uno::Any> aArguments2(comphelper::InitAnyPropertySequence(
1166 {"nodepath", css::uno::Any(u"org.openoffice.Office.Java/VirtualMachine"_ustr)},
1167 {"depth", css::uno::Any(sal_Int32(-1))} // depth: -1 means unlimited
1168 }));
1169 m_xJavaConfiguration.set(
1170 xConfigProvider->createInstanceWithArguments(
1171 u"com.sun.star.configuration.ConfigurationAccess"_ustr,
1172 aArguments2),
1173 css::uno::UNO_QUERY);
1175 if (m_xJavaConfiguration.is())
1176 m_xJavaConfiguration->addContainerListener(this);
1178 }catch(const css::uno::Exception & e)
1180 SAL_INFO("stoc", "could not set up listener for Configuration because of >" << e << "<");
1184 // param true: all Inet setting are set as Java Properties on a live VM.
1185 // false: the Java net properties are set to empty value.
1186 void JavaVirtualMachine::setINetSettingsInVM(bool set_reset)
1188 osl::MutexGuard aGuard(m_aMutex);
1191 if (m_xUnoVirtualMachine.is())
1193 jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
1194 m_xUnoVirtualMachine->getVirtualMachine());
1195 JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1197 // The Java Properties
1198 OUString sHttpProxyHost(u"http.proxyHost"_ustr);
1199 OUString sHttpProxyPort(u"http.proxyPort"_ustr);
1200 OUString sHttpNonProxyHosts(u"http.nonProxyHosts"_ustr);
1202 // create Java Properties as JNI strings
1203 jstring jsHttpProxyHost= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyHost.getStr()), sHttpProxyHost.getLength());
1204 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1205 jstring jsHttpProxyPort= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpProxyPort.getStr()), sHttpProxyPort.getLength());
1206 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1207 jstring jsHttpNonProxyHosts= pJNIEnv->NewString( reinterpret_cast<jchar const *>(sHttpNonProxyHosts.getStr()), sHttpNonProxyHosts.getLength());
1208 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1210 // prepare java.lang.System.setProperty
1211 jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1212 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:FindClass java/lang/System"_ustr, nullptr);
1213 jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1214 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetStaticMethodID java.lang.System.setProperty"_ustr, nullptr);
1216 // call java.lang.System.getProperties
1217 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1218 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetStaticMethodID java.lang.System.getProperties"_ustr, nullptr);
1219 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1220 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.getProperties"_ustr, nullptr);
1221 // prepare java.util.Properties.remove
1222 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1223 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:FindClass java/util/Properties"_ustr, nullptr);
1225 if (set_reset)
1227 // Set all network properties with the VM
1228 JVM jvm;
1229 getINetPropsFromConfig( &jvm, m_xContext->getServiceManager(), m_xContext);
1230 const ::std::vector< OUString> & Props = jvm.getProperties();
1232 for( auto& prop : Props)
1234 sal_Int32 index= prop.indexOf( '=');
1235 std::u16string_view propName= prop.subView( 0, index);
1236 OUString propValue= prop.copy( index + 1);
1238 if (propName == sHttpProxyHost)
1240 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1241 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1242 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyHost, jsVal);
1243 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.setProperty"_ustr, nullptr);
1245 else if( propName == sHttpProxyPort)
1247 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1248 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1249 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyPort, jsVal);
1250 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.setProperty"_ustr, nullptr);
1252 else if( propName == sHttpNonProxyHosts)
1254 jstring jsVal= pJNIEnv->NewString( reinterpret_cast<jchar const *>(propValue.getStr()), propValue.getLength());
1255 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:NewString"_ustr, nullptr);
1256 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpNonProxyHosts, jsVal);
1257 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:CallStaticObjectMethod java.lang.System.setProperty"_ustr, nullptr);
1261 else
1263 // call java.util.Properties.remove
1264 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1265 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(u"JNI:GetMethodID java.util.Property.remove"_ustr, nullptr);
1266 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyHost);
1267 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyPort);
1268 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpNonProxyHosts);
1272 catch (css::uno::RuntimeException &)
1274 OSL_FAIL("RuntimeException");
1276 catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1278 OSL_FAIL("jvmaccess::VirtualMachine::AttachGuard::CreationException");
1282 void JavaVirtualMachine::setUpUnoVirtualMachine(JNIEnv * environment) {
1283 css::uno::Reference< css::util::XMacroExpander > exp = css::util::theMacroExpander::get(m_xContext);
1284 OUString baseUrl;
1285 try {
1286 baseUrl = exp->expandMacros(u"$URE_INTERNAL_JAVA_DIR/"_ustr);
1287 } catch (css::lang::IllegalArgumentException &) {
1288 css::uno::Any anyEx = cppu::getCaughtException();
1289 throw css::lang::WrappedTargetRuntimeException(
1290 u"css::lang::IllegalArgumentException"_ustr,
1291 getXWeak(), anyEx );
1293 OUString classPath;
1294 try {
1295 classPath = exp->expandMacros(u"$URE_INTERNAL_JAVA_CLASSPATH"_ustr);
1296 } catch (css::lang::IllegalArgumentException &) {}
1297 jclass class_URLClassLoader = environment->FindClass(
1298 "java/net/URLClassLoader");
1299 if (class_URLClassLoader == nullptr) {
1300 handleJniException(environment);
1302 jmethodID ctor_URLClassLoader = environment->GetMethodID(
1303 class_URLClassLoader, "<init>", "([Ljava/net/URL;)V");
1304 if (ctor_URLClassLoader == nullptr) {
1305 handleJniException(environment);
1307 jclass class_URL = environment->FindClass("java/net/URL");
1308 if (class_URL == nullptr) {
1309 handleJniException(environment);
1311 jmethodID ctor_URL_1 = environment->GetMethodID(
1312 class_URL, "<init>", "(Ljava/lang/String;)V");
1313 if (ctor_URL_1 == nullptr) {
1314 handleJniException(environment);
1316 jvalue args[3];
1317 args[0].l = environment->NewString(
1318 reinterpret_cast< jchar const * >(baseUrl.getStr()),
1319 static_cast< jsize >(baseUrl.getLength()));
1320 if (args[0].l == nullptr) {
1321 handleJniException(environment);
1323 jobject base = environment->NewObjectA(class_URL, ctor_URL_1, args);
1324 if (base == nullptr) {
1325 handleJniException(environment);
1327 jmethodID ctor_URL_2 = environment->GetMethodID(
1328 class_URL, "<init>", "(Ljava/net/URL;Ljava/lang/String;)V");
1329 if (ctor_URL_2 == nullptr) {
1330 handleJniException(environment);
1332 jobjectArray classpath = jvmaccess::ClassPath::translateToUrls(
1333 m_xContext, environment, classPath);
1334 if (classpath == nullptr) {
1335 handleJniException(environment);
1337 args[0].l = base;
1338 args[1].l = environment->NewStringUTF("unoloader.jar");
1339 if (args[1].l == nullptr) {
1340 handleJniException(environment);
1342 args[0].l = environment->NewObjectA(class_URL, ctor_URL_2, args);
1343 if (args[0].l == nullptr) {
1344 handleJniException(environment);
1346 args[0].l = environment->NewObjectArray(1, class_URL, args[0].l);
1347 if (args[0].l == nullptr) {
1348 handleJniException(environment);
1350 jobject cl1 = environment->NewObjectA(
1351 class_URLClassLoader, ctor_URLClassLoader, args);
1352 if (cl1 == nullptr) {
1353 handleJniException(environment);
1355 jmethodID method_loadClass = environment->GetMethodID(
1356 class_URLClassLoader, "loadClass",
1357 "(Ljava/lang/String;)Ljava/lang/Class;");
1358 if (method_loadClass == nullptr) {
1359 handleJniException(environment);
1361 args[0].l = environment->NewStringUTF(
1362 "com.sun.star.lib.unoloader.UnoClassLoader");
1363 if (args[0].l == nullptr) {
1364 handleJniException(environment);
1366 jclass class_UnoClassLoader = static_cast< jclass >(
1367 environment->CallObjectMethodA(cl1, method_loadClass, args));
1368 if (class_UnoClassLoader == nullptr) {
1369 handleJniException(environment);
1371 jmethodID ctor_UnoClassLoader = environment->GetMethodID(
1372 class_UnoClassLoader, "<init>",
1373 "(Ljava/net/URL;[Ljava/net/URL;Ljava/lang/ClassLoader;)V");
1374 if (ctor_UnoClassLoader == nullptr) {
1375 handleJniException(environment);
1377 args[0].l = base;
1378 args[1].l = classpath;
1379 args[2].l = cl1;
1380 jobject cl2 = environment->NewObjectA(
1381 class_UnoClassLoader, ctor_UnoClassLoader, args);
1382 if (cl2 == nullptr) {
1383 handleJniException(environment);
1385 try {
1386 m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(
1387 m_xVirtualMachine, cl2);
1388 } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
1389 css::uno::Any anyEx = cppu::getCaughtException();
1390 throw css::lang::WrappedTargetRuntimeException(
1391 u"jvmaccess::UnoVirtualMachine::CreationException"_ustr,
1392 getXWeak(), anyEx );
1396 void JavaVirtualMachine::handleJniException(JNIEnv * environment) {
1397 #if defined DBG_UTIL
1398 environment->ExceptionDescribe();
1399 #else
1400 environment->ExceptionClear();
1401 #endif
1402 throw css::uno::RuntimeException(
1403 u"JNI exception occurred"_ustr,
1404 getXWeak());
1408 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1409 stoc_JavaVM_get_implementation(
1410 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
1412 return cppu::acquire(new JavaVirtualMachine(context));
1416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */