1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
73 // Properties of the javavm can be put
74 // as a comma separated list in this
75 // environment variable
77 #define TIMEZONE "MEZ"
79 #define TIMEZONE "MET"
84 #include <CoreFoundation/CoreFoundation.h>
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
;
111 class NoJavaIniException
: public css::uno::Exception
115 typedef std::stack
< jvmaccess::VirtualMachine::AttachGuard
* > GuardStack
;
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();
135 bool askForRetry(css::uno::Any
const & rException
)
137 if (comphelper::IsContextFlagActive(u
"DontEnableJava"_ustr
))
140 css::uno::Reference
< css::uno::XCurrentContext
> xContext(
141 css::uno::getCurrentContext());
144 css::uno::Reference
< css::task::XInteractionHandler
> xHandler
;
145 xContext
->getValueByName(u
"java-vm.interaction-handler"_ustr
)
149 rtl::Reference
< stoc_javavm::InteractionRequest
> xRequest(
150 new stoc_javavm::InteractionRequest(rException
));
151 xHandler
->handle(xRequest
);
152 return xRequest
->retry();
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
,
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());
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());
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
,
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
,
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();
354 case 0: sVal
= "host";
356 case 1: sVal
= "unrestricted";
358 case 3: sVal
= "none";
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
);
371 sProperty
+= "false";
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"
388 time_t clock
= time(nullptr);
390 tmData
= localtime(&clock
);
392 char * p
= tmData
->tm_zone
;
393 #elif defined(_MSC_VER)
394 char * p
= _tzname
[0];
397 char * p
= tzname
[0];
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
;
413 getINetPropsFromConfig(&jvm
, xSMgr
, xCtx
);
415 catch(const css::uno::Exception
& exception
) {
416 SAL_INFO("stoc", "can not get INETProps because of " << exception
);
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
);
446 class DetachCurrentThread
{
448 explicit DetachCurrentThread(JavaVM
* jvm
): m_jvm(jvm
) {}
450 ~DetachCurrentThread() {
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())
460 if (m_jvm
->DetachCurrentThread() != 0) {
465 DetachCurrentThread(const DetachCurrentThread
&) = delete;
466 DetachCurrentThread
& operator=(const DetachCurrentThread
&) = delete;
474 JavaVirtualMachine::JavaVirtualMachine(
475 css::uno::Reference
< css::uno::XComponentContext
> xContext
):
476 WeakComponentImplHelper(m_aMutex
),
477 m_xContext(std::move(xContext
)),
480 m_aAttachGuards(destroyAttachGuards
) // TODO check for validity
484 JavaVirtualMachine::initialize(css::uno::Sequence
< css::uno::Any
> const &
487 osl::MutexGuard
aGuard(m_aMutex
);
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
,
495 css::beans::NamedValue val
;
496 if (rArguments
.getLength() == 1 && (rArguments
[0] >>= val
) && val
.Name
== "UnoVirtualMachine" )
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
);
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
));
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
,
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
,
537 m_xVirtualMachine
= m_xUnoVirtualMachine
->getVirtualMachine();
540 OUString SAL_CALL
JavaVirtualMachine::getImplementationName()
542 return u
"com.sun.star.comp.stoc.JavaVirtualMachine"_ustr
;
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
);
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()));
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
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(),
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
;
600 errcode
= jfw_startVM(info
.get(), options
, & m_pJavaVm
,
603 bool bStarted
= false;
606 case JFW_E_NONE
: bStarted
= true; break;
607 case JFW_E_NO_SELECT
:
609 // No Java configured. We silently run the Java configuration
611 javaFrameworkError errFind
;
612 if (getenv("STOC_FORCE_NO_JRE"))
613 errFind
= JFW_E_NO_JAVA_FOUND
;
615 errFind
= jfw_findAndSelectJRE(&info
);
616 if (errFind
== JFW_E_NONE
)
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
,
630 askForRetry(css::uno::Any(exc
));
631 return css::uno::Any();
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
,
651 askForRetry(css::uno::Any(exc
));
652 return css::uno::Any();
654 case JFW_E_JAVA_DISABLED
:
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
,
663 if( ! askForRetry(css::uno::Any(exc
)))
664 return css::uno::Any();
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
673 std::unique_ptr
<JavaInfo
> aJavaInfo
;
674 if (JFW_E_NONE
== jfw_getSelectedJRE(&aJavaInfo
))
677 if (JFW_E_NONE
== jfw_existJRE(aJavaInfo
.get(), &bExist
))
680 && ! (aJavaInfo
->nRequirements
& JFW_REQUIRE_NEEDRESTART
))
683 javaFrameworkError errFind
= jfw_findAndSelectJRE(
685 if (errFind
== JFW_E_NONE
)
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
,
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.
709 case JFW_E_NEED_RESTART
:
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
,
718 askForRetry(css::uno::Any(exc
));
719 return css::uno::Any();
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);
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();
747 if (!m_xUnoVirtualMachine
.is()) {
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
,
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
,
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
);
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
);
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();
800 bool bEnabled
= false;
801 if (jfw_getEnabled( & bEnabled
) != JFW_E_NONE
)
802 throw css::uno::RuntimeException();
806 sal_Bool SAL_CALL
JavaVirtualMachine::isThreadAttached()
808 osl::MutexGuard
aGuard(m_aMutex
);
810 throw css::lang::DisposedException(
811 OUString(), getXWeak());
812 // TODO isThreadAttached only returns true if the thread was attached via
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
);
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
,
830 = static_cast< GuardStack
* >(m_aAttachGuards
.getData());
831 if (pStack
== nullptr)
833 pStack
= new GuardStack
;
834 m_aAttachGuards
.setData(pStack
);
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
,
852 void SAL_CALL
JavaVirtualMachine::revokeThread()
854 osl::MutexGuard
aGuard(m_aMutex
);
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
,
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
,
868 delete pStack
->top();
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
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.
905 rEvent
.Accessor
>>= aAccessor
;
906 OUString aPropertyName
;
907 OUString aPropertyValue
;
908 bool bSecurityChanged
= false;
909 if ( aAccessor
== "ooInetProxyType" )
911 // Proxy none, manually
913 rEvent
.Element
>>= value
;
914 setINetSettingsInVM(value
!= 0);
917 else if ( aAccessor
== "ooInetHTTPProxyName" )
919 aPropertyName
= "http.proxyHost";
920 rEvent
.Element
>>= aPropertyValue
;
922 else if ( aAccessor
== "ooInetHTTPProxyPort" )
924 aPropertyName
= "http.proxyPort";
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";
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";
951 if (rEvent
.Element
>>= n
)
955 aPropertyValue
= "host";
958 aPropertyValue
= "unrestricted";
961 aPropertyValue
= "none";
966 bSecurityChanged
= true;
968 else if ( aAccessor
== "Security" )
970 aPropertyName
= "stardiv.security.disableSecurity";
972 if (rEvent
.Element
>>= b
)
974 aPropertyValue
= "false";
976 aPropertyValue
= "true";
979 bSecurityChanged
= true;
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())
996 jvmaccess::VirtualMachine::AttachGuard
aAttachGuard(
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
);
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
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
));
1065 bIsSandbox
= sName
== "com.sun.star.lib.sandbox.SandboxSecurity";
1066 pJNIEnv
->ReleaseStringChars( jsClass
, jcharName
);
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
);
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)
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))}
1154 m_xInetConfiguration
.set(
1155 xConfigProvider
->createInstanceWithArguments(
1156 u
"com.sun.star.configuration.ConfigurationAccess"_ustr
,
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
1169 m_xJavaConfiguration
.set(
1170 xConfigProvider
->createInstanceWithArguments(
1171 u
"com.sun.star.configuration.ConfigurationAccess"_ustr
,
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);
1227 // Set all network properties with the VM
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);
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
);
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
);
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
);
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
);
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
);
1378 args
[1].l
= classpath
;
1380 jobject cl2
= environment
->NewObjectA(
1381 class_UnoClassLoader
, ctor_UnoClassLoader
, args
);
1382 if (cl2
== nullptr) {
1383 handleJniException(environment
);
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();
1400 environment
->ExceptionClear();
1402 throw css::uno::RuntimeException(
1403 u
"JNI exception occurred"_ustr
,
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: */