xref: /trunk/main/stoc/source/javavm/javavm.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 
27 #include "javavm.hxx"
28 
29 #include "interact.hxx"
30 #include "jvmargs.hxx"
31 
32 #include "com/sun/star/beans/NamedValue.hpp"
33 #include "com/sun/star/beans/PropertyState.hpp"
34 #include "com/sun/star/beans/PropertyValue.hpp"
35 #include "com/sun/star/container/XContainer.hpp"
36 #include "com/sun/star/java/JavaNotFoundException.hpp"
37 #include "com/sun/star/java/InvalidJavaSettingsException.hpp"
38 #include "com/sun/star/java/RestartRequiredException.hpp"
39 #include "com/sun/star/java/JavaDisabledException.hpp"
40 #include "com/sun/star/java/JavaVMCreationFailureException.hpp"
41 #include "com/sun/star/lang/DisposedException.hpp"
42 #include "com/sun/star/lang/IllegalArgumentException.hpp"
43 #include "com/sun/star/lang/XEventListener.hpp"
44 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
45 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
46 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
47 #include "com/sun/star/registry/XRegistryKey.hpp"
48 #include "com/sun/star/registry/XSimpleRegistry.hpp"
49 #include "com/sun/star/task/XInteractionHandler.hpp"
50 #include "com/sun/star/uno/Exception.hpp"
51 #include "com/sun/star/uno/Reference.hxx"
52 #include "com/sun/star/uno/RuntimeException.hpp"
53 #include "com/sun/star/uno/Sequence.hxx"
54 #include "com/sun/star/uno/XComponentContext.hpp"
55 #include "com/sun/star/uno/XCurrentContext.hpp"
56 #include "com/sun/star/uno/XInterface.hpp"
57 #include "com/sun/star/util/XMacroExpander.hpp"
58 #include "com/sun/star/container/XNameAccess.hpp"
59 #include "cppuhelper/exc_hlp.hxx"
60 #include "cppuhelper/factory.hxx"
61 #include "cppuhelper/implbase1.hxx"
62 #include "cppuhelper/implementationentry.hxx"
63 #include "jvmaccess/classpath.hxx"
64 #include "jvmaccess/unovirtualmachine.hxx"
65 #include "jvmaccess/virtualmachine.hxx"
66 #include "osl/file.hxx"
67 #include "osl/thread.h"
68 #include "rtl/bootstrap.hxx"
69 #include "rtl/process.h"
70 #include "rtl/string.h"
71 #include "rtl/ustrbuf.hxx"
72 #include "rtl/ustring.h"
73 #include "rtl/ustring.hxx"
74 #include "rtl/uri.hxx"
75 #include "sal/types.h"
76 #include "uno/current_context.hxx"
77 #include "uno/environment.h"
78 #include "uno/lbnames.h"
79 #include "jvmfwk/framework.h"
80 #include "jni.h"
81 
82 #include <stack>
83 #include <string.h>
84 #include <time.h>
85 #include <memory>
86 #include <vector>
87 #include "boost/scoped_array.hpp"
88 #define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
89 
90 // Properties of the javavm can be put
91 // as a komma separated list in this
92 // environment variable
93 #define PROPERTIES_ENV "OO_JAVA_PROPERTIES"
94 #ifdef UNIX
95 #define INI_FILE "javarc"
96 #ifdef MACOSX
97 #define DEF_JAVALIB "JavaVM.framework"
98 #else
99 #define DEF_JAVALIB "libjvm.so"
100 #endif
101 #define TIMEZONE "MEZ"
102 #else
103 #define INI_FILE "java.ini"
104 #define DEF_JAVALIB "jvm.dll"
105 #define TIMEZONE "MET"
106 #endif
107 
108 /* Within this implementation of the com.sun.star.java.JavaVirtualMachine
109  * service and com.sun.star.java.theJavaVirtualMachine singleton, the method
110  * com.sun.star.java.XJavaVM.getJavaVM relies on the following:
111  * 1  The string "$URE_INTERNAL_JAVA_DIR/" is expanded via the
112  * com.sun.star.util.theMacroExpander singleton into an internal (see the
113  * com.sun.star.uri.ExternalUriReferenceTranslator service), hierarchical URI
114  * reference relative to which the URE JAR files can be addressed.
115  * 2  The string "$URE_INTERNAL_JAVA_CLASSPATH" is either not expandable via the
116  * com.sun.star.util.theMacroExpander singleton
117  * (com.sun.star.lang.IllegalArgumentException), or is expanded via the
118  * com.sun.star.util.theMacroExpander singleton into a list of zero or more
119  * internal (see the com.sun.star.uri.ExternalUriReferenceTranslator service)
120  * URIs, where any space characters (U+0020) are ignored (and, in particular,
121  * separate adjacent URIs).
122  * If either of these requirements is not met, getJavaVM raises a
123  * com.sun.star.uno.RuntimeException.
124  */
125 
126 namespace css = com::sun::star;
127 
128 using stoc_javavm::JavaVirtualMachine;
129 
130 namespace {
131 
132 
133 
134 class NoJavaIniException: public css::uno::Exception
135 {
136 };
137 
138 class SingletonFactory:
139     private cppu::WeakImplHelper1< css::lang::XEventListener >
140 {
141 public:
142     static css::uno::Reference< css::uno::XInterface > getSingleton(
143         css::uno::Reference< css::uno::XComponentContext > const & rContext);
144 
145 private:
146     SingletonFactory(SingletonFactory &); // not implemented
147     void operator =(SingletonFactory); // not implemented
148 
SingletonFactory()149     inline SingletonFactory() {}
150 
~SingletonFactory()151     virtual inline ~SingletonFactory() {}
152 
153     virtual void SAL_CALL disposing(css::lang::EventObject const &);
154 
155     static void dispose();
156 
157     // TODO ok to keep these static?
158     static osl::Mutex m_aMutex;
159     static css::uno::Reference< css::uno::XInterface > m_xSingleton;
160     static bool m_bDisposed;
161 };
162 
getSingleton(css::uno::Reference<css::uno::XComponentContext> const & rContext)163 css::uno::Reference< css::uno::XInterface > SingletonFactory::getSingleton(
164     css::uno::Reference< css::uno::XComponentContext > const & rContext)
165 {
166     css::uno::Reference< css::uno::XInterface > xSingleton;
167     css::uno::Reference< css::lang::XComponent > xComponent;
168     {
169         osl::MutexGuard aGuard(m_aMutex);
170         if (!m_xSingleton.is())
171         {
172             if (m_bDisposed)
173                 throw css::lang::DisposedException();
174             xComponent = css::uno::Reference< css::lang::XComponent >(
175                 rContext, css::uno::UNO_QUERY_THROW);
176             m_xSingleton = static_cast< cppu::OWeakObject * >(
177                 new JavaVirtualMachine(rContext));
178         }
179         xSingleton = m_xSingleton;
180     }
181     if (xComponent.is())
182         try
183         {
184             xComponent->addEventListener(new SingletonFactory);
185         }
186         catch (...)
187         {
188             dispose();
189             throw;
190         }
191     return xSingleton;
192 }
193 
disposing(css::lang::EventObject const &)194 void SAL_CALL SingletonFactory::disposing(css::lang::EventObject const &)
195 {
196     dispose();
197 }
198 
dispose()199 void SingletonFactory::dispose()
200 {
201     css::uno::Reference< css::lang::XComponent > xComponent;
202     {
203         osl::MutexGuard aGuard(m_aMutex);
204         xComponent = css::uno::Reference< css::lang::XComponent >(
205             m_xSingleton, css::uno::UNO_QUERY);
206         m_xSingleton.clear();
207         m_bDisposed = true;
208     }
209     if (xComponent.is())
210         xComponent->dispose();
211 }
212 
213 osl::Mutex SingletonFactory::m_aMutex;
214 css::uno::Reference< css::uno::XInterface > SingletonFactory::m_xSingleton;
215 bool SingletonFactory::m_bDisposed = false;
216 
serviceGetImplementationName()217 rtl::OUString serviceGetImplementationName()
218 {
219     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
220                              "com.sun.star.comp.stoc.JavaVirtualMachine"));
221 }
222 
serviceGetSupportedServiceNames()223 css::uno::Sequence< rtl::OUString > serviceGetSupportedServiceNames()
224 {
225     rtl::OUString aServiceName(
226         RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine"));
227     return css::uno::Sequence< rtl::OUString >(&aServiceName, 1);
228 }
229 
serviceCreateInstance(css::uno::Reference<css::uno::XComponentContext> const & rContext)230 css::uno::Reference< css::uno::XInterface > SAL_CALL serviceCreateInstance(
231     css::uno::Reference< css::uno::XComponentContext > const & rContext)
232 {
233     // Only one single instance of this service is ever constructed, and is
234     // available until the component context used to create this instance is
235     // disposed.  Afterwards, this function throws a DisposedException (as do
236     // all relevant methods on the single service instance).
237     return SingletonFactory::getSingleton(rContext);
238 }
239 
240 cppu::ImplementationEntry const aServiceImplementation[]
241     = { { serviceCreateInstance,
242           serviceGetImplementationName,
243           serviceGetSupportedServiceNames,
244           cppu::createSingleComponentFactory,
245           0, 0 },
246         { 0, 0, 0, 0, 0, 0 } };
247 
248 typedef std::stack< jvmaccess::VirtualMachine::AttachGuard * > GuardStack;
249 
250 extern "C" {
251 
destroyAttachGuards(void * pData)252 static void destroyAttachGuards(void * pData)
253 {
254     GuardStack * pStack = static_cast< GuardStack * >(pData);
255     if (pStack != 0)
256     {
257         while (!pStack->empty())
258         {
259             delete pStack->top();
260             pStack->pop();
261         }
262         delete pStack;
263     }
264 }
265 
266 }
267 
askForRetry(css::uno::Any const & rException)268 bool askForRetry(css::uno::Any const & rException)
269 {
270     css::uno::Reference< css::uno::XCurrentContext > xContext(
271         css::uno::getCurrentContext());
272     if (xContext.is())
273     {
274         css::uno::Reference< css::task::XInteractionHandler > xHandler;
275         xContext->getValueByName(rtl::OUString(
276                                      RTL_CONSTASCII_USTRINGPARAM(
277                                          "java-vm.interaction-handler")))
278             >>= xHandler;
279         if (xHandler.is())
280         {
281             rtl::Reference< stoc_javavm::InteractionRequest > xRequest(
282                 new stoc_javavm::InteractionRequest(rException));
283             xHandler->handle(xRequest.get());
284             return xRequest->retry();
285         }
286     }
287     return false;
288 }
289 
290 // Only gets the properties if the "Proxy Server" entry in the option dialog is
291 // set to manual (i.e. not to none)
getINetPropsFromConfig(stoc_javavm::JVM * pjvm,const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,const css::uno::Reference<css::uno::XComponentContext> & xCtx)292 void getINetPropsFromConfig(stoc_javavm::JVM * pjvm,
293                             const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
294                             const css::uno::Reference<css::uno::XComponentContext> &xCtx )
295 {
296     css::uno::Reference<css::uno::XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
297             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry")),
298             xCtx );
299     if(!xConfRegistry.is()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
300 
301     css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(xConfRegistry, css::uno::UNO_QUERY);
302     if(!xConfRegistry_simple.is()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
303 
304     xConfRegistry_simple->open(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet")), sal_True, sal_False);
305     css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
306 
307 //  if ooInetProxyType is not 0 then read the settings
308     css::uno::Reference<css::registry::XRegistryKey> proxyEnable= xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetProxyType")));
309     if( proxyEnable.is() && 0 != proxyEnable->getLongValue())
310     {
311         // read ftp proxy name
312         css::uno::Reference<css::registry::XRegistryKey> ftpProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyName")));
313         if(ftpProxy_name.is() && ftpProxy_name->getStringValue().getLength()) {
314             rtl::OUString ftpHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyHost="));
315             ftpHost += ftpProxy_name->getStringValue();
316 
317             // read ftp proxy port
318             css::uno::Reference<css::registry::XRegistryKey> ftpProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyPort")));
319             if(ftpProxy_port.is() && ftpProxy_port->getLongValue()) {
320                 rtl::OUString ftpPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort="));
321                 ftpPort += rtl::OUString::valueOf(ftpProxy_port->getLongValue());
322 
323                 pjvm->pushProp(ftpHost);
324                 pjvm->pushProp(ftpPort);
325             }
326         }
327 
328         // read http proxy name
329         css::uno::Reference<css::registry::XRegistryKey> httpProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyName")));
330         if(httpProxy_name.is() && httpProxy_name->getStringValue().getLength()) {
331             rtl::OUString httpHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyHost="));
332             httpHost += httpProxy_name->getStringValue();
333 
334             // read http proxy port
335             css::uno::Reference<css::registry::XRegistryKey> httpProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyPort")));
336             if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
337                 rtl::OUString httpPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort="));
338                 httpPort += rtl::OUString::valueOf(httpProxy_port->getLongValue());
339 
340                 pjvm->pushProp(httpHost);
341                 pjvm->pushProp(httpPort);
342             }
343         }
344 
345         // read https proxy name
346         css::uno::Reference<css::registry::XRegistryKey> httpsProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPSProxyName")));
347         if(httpsProxy_name.is() && httpsProxy_name->getStringValue().getLength()) {
348             rtl::OUString httpsHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyHost="));
349             httpsHost += httpsProxy_name->getStringValue();
350 
351             // read https proxy port
352             css::uno::Reference<css::registry::XRegistryKey> httpsProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPSProxyPort")));
353             if(httpsProxy_port.is() && httpsProxy_port->getLongValue()) {
354                 rtl::OUString httpsPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyPort="));
355                 httpsPort += rtl::OUString::valueOf(httpsProxy_port->getLongValue());
356 
357                 pjvm->pushProp(httpsHost);
358                 pjvm->pushProp(httpsPort);
359             }
360         }
361 
362         // read  nonProxyHosts
363         css::uno::Reference<css::registry::XRegistryKey> nonProxies_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetNoProxy")));
364         if(nonProxies_name.is() && nonProxies_name->getStringValue().getLength()) {
365             rtl::OUString httpNonProxyHosts = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.nonProxyHosts="));
366             rtl::OUString ftpNonProxyHosts= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.nonProxyHosts="));
367             rtl::OUString value= nonProxies_name->getStringValue();
368             // replace the separator ";" by "|"
369             value= value.replace((sal_Unicode)';', (sal_Unicode)'|');
370 
371             httpNonProxyHosts += value;
372             ftpNonProxyHosts += value;
373 
374             pjvm->pushProp(httpNonProxyHosts);
375             pjvm->pushProp(ftpNonProxyHosts);
376         }
377 
378         // read socks settings
379 /*      Reference<XRegistryKey> socksProxy_name = xRegistryRootKey->openKey(OUSTR("Settings/ooInetSOCKSProxyName"));
380         if (socksProxy_name.is() && httpProxy_name->getStringValue().getLength()) {
381             OUString socksHost = OUSTR("socksProxyHost=");
382             socksHost += socksProxy_name->getStringValue();
383 
384             // read http proxy port
385             Reference<XRegistryKey> socksProxy_port = xRegistryRootKey->openKey(OUSTR("Settings/ooInetSOCKSProxyPort"));
386             if (socksProxy_port.is() && socksProxy_port->getLongValue()) {
387                 OUString socksPort = OUSTR("socksProxyPort=");
388                 socksPort += OUString::valueOf(socksProxy_port->getLongValue());
389 
390                 pjvm->pushProp(socksHost);
391                 pjvm->pushProp(socksPort);
392             }
393         }
394 */  }
395     xConfRegistry_simple->close();
396 }
397 
getDefaultLocaleFromConfig(stoc_javavm::JVM * pjvm,const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,const css::uno::Reference<css::uno::XComponentContext> & xCtx)398 void getDefaultLocaleFromConfig(
399     stoc_javavm::JVM * pjvm,
400     const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
401     const css::uno::Reference<css::uno::XComponentContext> &xCtx )
402 {
403     css::uno::Reference<css::uno::XInterface> xConfRegistry =
404         xSMgr->createInstanceWithContext(
405         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
406                           "com.sun.star.configuration.ConfigurationRegistry")), xCtx );
407     if(!xConfRegistry.is())
408         throw css::uno::RuntimeException(
409             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
410 
411     css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
412         xConfRegistry, css::uno::UNO_QUERY);
413     if(!xConfRegistry_simple.is())
414         throw css::uno::RuntimeException(
415             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
416 
417     xConfRegistry_simple->open(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")), sal_True, sal_False);
418     css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
419 
420     // read locale
421     css::uno::Reference<css::registry::XRegistryKey> ooLocale = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("L10N/ooLocale")));
422     css::uno::Reference<css::registry::XRegistryKey> ooSetupSystemLocale = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("L10N/ooSetupSystemLocale")));
423     if(ooLocale.is() && ooLocale->getStringValue().getLength()) {
424         rtl::OUString language;
425         sal_Int32 index = ooLocale->getStringValue().indexOf((sal_Unicode) '-');
426         if(index >= 0) {
427             language = ooLocale->getStringValue().copy(0, index);
428         } else {
429             language = ooLocale->getStringValue();
430         }
431         if(language.getLength()) {
432             rtl::OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.language="));
433             prop += language;
434             pjvm->pushProp(prop);
435         }
436     }
437     if(ooSetupSystemLocale.is() && ooSetupSystemLocale->getStringValue().getLength()) {
438         sal_Int32 index = ooSetupSystemLocale->getStringValue().indexOf((sal_Unicode) '-');
439         if(index >= 0) {
440             rtl::OUString country = ooSetupSystemLocale->getStringValue().copy(index + 1);
441             if(country.getLength()) {
442                 rtl::OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.country="));
443                 prop += country;
444                 pjvm->pushProp(prop);
445             }
446         }
447     }
448 
449     xConfRegistry_simple->close();
450 }
451 
452 
453 
getJavaPropsFromSafetySettings(stoc_javavm::JVM * pjvm,const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,const css::uno::Reference<css::uno::XComponentContext> & xCtx)454 void getJavaPropsFromSafetySettings(
455     stoc_javavm::JVM * pjvm,
456     const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
457     const css::uno::Reference<css::uno::XComponentContext> &xCtx)
458 {
459     css::uno::Reference<css::uno::XInterface> xConfRegistry =
460         xSMgr->createInstanceWithContext(
461             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
462                               "com.sun.star.configuration.ConfigurationRegistry")),
463             xCtx);
464     if(!xConfRegistry.is())
465         throw css::uno::RuntimeException(
466             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
467 
468     css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
469         xConfRegistry, css::uno::UNO_QUERY);
470     if(!xConfRegistry_simple.is())
471         throw css::uno::RuntimeException(
472             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
473 
474     xConfRegistry_simple->open(
475         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Java")),
476         sal_True, sal_False);
477     css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey =
478         xConfRegistry_simple->getRootKey();
479 
480     if (xRegistryRootKey.is())
481     {
482         css::uno::Reference<css::registry::XRegistryKey> key_NetAccess= xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VirtualMachine/NetAccess")));
483         if (key_NetAccess.is())
484         {
485             sal_Int32 val= key_NetAccess->getLongValue();
486             rtl::OUString sVal;
487             switch( val)
488             {
489             case 0: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"));
490                 break;
491             case 1: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unrestricted"));
492                 break;
493             case 3: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
494                 break;
495             }
496             rtl::OUString sProperty( RTL_CONSTASCII_USTRINGPARAM("appletviewer.security.mode="));
497             sProperty= sProperty + sVal;
498             pjvm->pushProp(sProperty);
499         }
500         css::uno::Reference<css::registry::XRegistryKey> key_CheckSecurity= xRegistryRootKey->openKey(
501             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VirtualMachine/Security")));
502         if( key_CheckSecurity.is())
503         {
504             sal_Bool val= (sal_Bool) key_CheckSecurity->getLongValue();
505             rtl::OUString sProperty(RTL_CONSTASCII_USTRINGPARAM("stardiv.security.disableSecurity="));
506             if( val)
507                 sProperty= sProperty + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("false"));
508             else
509                 sProperty= sProperty + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"));
510             pjvm->pushProp( sProperty);
511         }
512     }
513     xConfRegistry_simple->close();
514 }
515 
setTimeZone(stoc_javavm::JVM * pjvm)516 static void setTimeZone(stoc_javavm::JVM * pjvm) throw() {
517     /* A Bug in the Java function
518     ** struct Hjava_util_Properties * java_lang_System_initProperties(
519     ** struct Hjava_lang_System *this,
520     ** struct Hjava_util_Properties *props);
521     ** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
522     */
523     struct tm *tmData;
524     time_t clock = time(NULL);
525     tzset();
526     tmData = localtime(&clock);
527 #ifdef MACOSX
528     char * p = tmData->tm_zone;
529 #elif defined(_MSC_VER) && (_MSC_VER >= 1900)
530     /*  The UCRT declares only the underscore spelling; the POSIX name was
531         removed.  glibc and VC9 keep it, so the branch below stays live. */
532     char * p = _tzname[0];
533 #else
534     char * p = tzname[0];
535 #endif
536 
537     if (!strcmp(TIMEZONE, p))
538         pjvm->pushProp(rtl::OUString::createFromAscii("user.timezone=ECT"));
539 }
540 
initVMConfiguration(stoc_javavm::JVM * pjvm,const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,const css::uno::Reference<css::uno::XComponentContext> & xCtx)541 void initVMConfiguration(
542     stoc_javavm::JVM * pjvm,
543     const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
544     const css::uno::Reference<css::uno::XComponentContext > &xCtx)
545 {
546     stoc_javavm::JVM jvm;
547     try {
548         getINetPropsFromConfig(&jvm, xSMgr, xCtx);
549     }
550     catch(css::uno::Exception & exception) {
551 #if OSL_DEBUG_LEVEL > 1
552         rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
553         OSL_TRACE("javavm.cxx: can not get INetProps cause of >%s<", message.getStr());
554 #else
555         (void) exception; // unused
556 #endif
557     }
558 
559     try {
560         getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
561     }
562     catch(css::uno::Exception & exception) {
563 #if OSL_DEBUG_LEVEL > 1
564         rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
565         OSL_TRACE("javavm.cxx: can not get locale cause of >%s<", message.getStr());
566 #else
567         (void) exception; // unused
568 #endif
569     }
570 
571     try
572     {
573         getJavaPropsFromSafetySettings(&jvm, xSMgr, xCtx);
574     }
575     catch(css::uno::Exception & exception) {
576 #if OSL_DEBUG_LEVEL > 1
577         rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
578         OSL_TRACE("javavm.cxx: couldn't get safety settings because of >%s<", message.getStr());
579 #else
580         (void) exception; // unused
581 #endif
582     }
583 
584     *pjvm= jvm;
585     setTimeZone(pjvm);
586 
587 }
588 
589 class DetachCurrentThread {
590 public:
DetachCurrentThread(JavaVM * jvm)591     explicit DetachCurrentThread(JavaVM * jvm): m_jvm(jvm) {}
592 
~DetachCurrentThread()593     ~DetachCurrentThread() {
594         if (m_jvm->DetachCurrentThread() != 0) {
595             OSL_ASSERT(false);
596         }
597     }
598 
599 private:
600     DetachCurrentThread(DetachCurrentThread &); // not defined
601     void operator =(DetachCurrentThread &); // not defined
602 
603     JavaVM * m_jvm;
604 };
605 
606 }
607 
608 extern "C" void SAL_CALL
component_getImplementationEnvironment(sal_Char const ** pEnvTypeName,uno_Environment **)609 component_getImplementationEnvironment(sal_Char const ** pEnvTypeName,
610                                        uno_Environment **)
611 {
612     *pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
613 }
614 
component_getFactory(sal_Char const * pImplName,void * pServiceManager,void * pRegistryKey)615 extern "C" void * SAL_CALL component_getFactory(sal_Char const * pImplName,
616                                                 void * pServiceManager,
617                                                 void * pRegistryKey)
618 {
619     return cppu::component_getFactoryHelper(pImplName, pServiceManager,
620                                             pRegistryKey,
621                                             aServiceImplementation);
622 }
623 
624 // There is no component_canUnload, as the library cannot be unloaded.
625 
JavaVirtualMachine(css::uno::Reference<css::uno::XComponentContext> const & rContext)626 JavaVirtualMachine::JavaVirtualMachine(
627     css::uno::Reference< css::uno::XComponentContext > const & rContext):
628     JavaVirtualMachine_Impl(*static_cast< osl::Mutex * >(this)),
629     m_xContext(rContext),
630     m_bDisposed(false),
631     m_pJavaVm(0),
632     m_bDontCreateJvm(false),
633     m_aAttachGuards(destroyAttachGuards) // TODO check for validity
634 {}
635 
636 void SAL_CALL
initialize(css::uno::Sequence<css::uno::Any> const & rArguments)637 JavaVirtualMachine::initialize(css::uno::Sequence< css::uno::Any > const &
638                                    rArguments)
639 {
640     osl::MutexGuard aGuard(*this);
641     if (m_bDisposed)
642         throw css::lang::DisposedException(
643             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
644     if (m_xUnoVirtualMachine.is())
645         throw css::uno::RuntimeException(
646             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
647                               "bad call to initialize")),
648             static_cast< cppu::OWeakObject * >(this));
649     css::beans::NamedValue val;
650     if (rArguments.getLength() == 1 && (rArguments[0] >>= val)
651         && val.Name.equalsAsciiL(
652             RTL_CONSTASCII_STRINGPARAM( "UnoVirtualMachine")))
653     {
654         OSL_ENSURE(
655             sizeof (sal_Int64) >= sizeof (jvmaccess::UnoVirtualMachine *),
656             "Pointer cannot be represented as sal_Int64");
657         sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
658             static_cast< jvmaccess::UnoVirtualMachine * >(0));
659         val.Value >>= nPointer;
660         m_xUnoVirtualMachine =
661             reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer);
662     } else {
663         OSL_ENSURE(
664             sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *),
665             "Pointer cannot be represented as sal_Int64");
666         sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
667             static_cast< jvmaccess::VirtualMachine * >(0));
668         if (rArguments.getLength() == 1)
669             rArguments[0] >>= nPointer;
670         rtl::Reference< jvmaccess::VirtualMachine > vm(
671             reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer));
672         if (vm.is()) {
673             try {
674                 m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(vm, 0);
675             } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
676                 throw css::uno::RuntimeException(
677                     rtl::OUString(
678                         RTL_CONSTASCII_USTRINGPARAM(
679                             "jvmaccess::UnoVirtualMachine::CreationException")),
680                     static_cast< cppu::OWeakObject * >(this));
681             }
682         }
683     }
684     if (!m_xUnoVirtualMachine.is()) {
685         throw css::lang::IllegalArgumentException(
686             rtl::OUString(
687                 RTL_CONSTASCII_USTRINGPARAM(
688                     "sequence of exactly one any containing either (a) a"
689                     " com.sun.star.beans.NamedValue with Name"
690                     " \"UnoVirtualMachine\" and Value a hyper representing a"
691                     " non-null pointer to a jvmaccess:UnoVirtualMachine, or (b)"
692                     " a hyper representing a non-null pointer to a"
693                     " jvmaccess::VirtualMachine required")),
694             static_cast< cppu::OWeakObject * >(this), 0);
695     }
696     m_xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
697 }
698 
getImplementationName()699 rtl::OUString SAL_CALL JavaVirtualMachine::getImplementationName()
700 {
701     return serviceGetImplementationName();
702 }
703 
704 sal_Bool SAL_CALL
supportsService(rtl::OUString const & rServiceName)705 JavaVirtualMachine::supportsService(rtl::OUString const & rServiceName)
706 {
707     css::uno::Sequence< rtl::OUString > aNames(getSupportedServiceNames());
708     for (sal_Int32 i = 0; i < aNames.getLength(); ++i)
709         if (aNames[i] == rServiceName)
710             return true;
711     return false;
712 }
713 
714 css::uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()715 JavaVirtualMachine::getSupportedServiceNames()
716 {
717     return serviceGetSupportedServiceNames();
718 }
719 
720 css::uno::Any SAL_CALL
getJavaVM(css::uno::Sequence<sal_Int8> const & rProcessId)721 JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
722 {
723     osl::MutexGuard aGuard(*this);
724     if (m_bDisposed)
725         throw css::lang::DisposedException(
726             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
727     css::uno::Sequence< sal_Int8 > aId(16);
728     rtl_getGlobalProcessId(reinterpret_cast< sal_uInt8 * >(aId.getArray()));
729     enum ReturnType {
730         RETURN_JAVAVM, RETURN_VIRTUALMACHINE, RETURN_UNOVIRTUALMACHINE };
731     ReturnType returnType =
732         rProcessId.getLength() == 17 && rProcessId[16] == 0
733         ? RETURN_VIRTUALMACHINE
734         : rProcessId.getLength() == 17 && rProcessId[16] == 1
735         ? RETURN_UNOVIRTUALMACHINE
736         : RETURN_JAVAVM;
737     css::uno::Sequence< sal_Int8 > aProcessId(rProcessId);
738     if (returnType != RETURN_JAVAVM)
739         aProcessId.realloc(16);
740     if (aId != aProcessId)
741         return css::uno::Any();
742 
743     while (!m_xVirtualMachine.is()) // retry until successful
744     {
745         // This is the second attempt to create Java.  m_bDontCreateJvm is
746         // set which means instantiating the JVM might crash.
747         if (m_bDontCreateJvm)
748             //throw css::uno::RuntimeException();
749             return css::uno::Any();
750 
751         stoc_javavm::JVM aJvm;
752         initVMConfiguration(&aJvm, m_xContext->getServiceManager(),
753                             m_xContext);
754         //Create the JavaVMOption array
755         const std::vector<rtl::OUString> & props = aJvm.getProperties();
756         boost::scoped_array<JavaVMOption> sarOptions(
757             new JavaVMOption[props.size()]);
758         JavaVMOption * arOptions = sarOptions.get();
759         //Create an array that contains the strings which are passed
760         //into the options
761         boost::scoped_array<rtl::OString> sarPropStrings(
762              new rtl::OString[props.size()]);
763         rtl::OString * arPropStrings = sarPropStrings.get();
764 
765         rtl::OString sJavaOption("-");
766         typedef std::vector<rtl::OUString>::const_iterator cit;
767         int index = 0;
768         for (cit i = props.begin(); i != props.end(); i++)
769         {
770             rtl::OString sOption = rtl::OUStringToOString(
771                 *i, osl_getThreadTextEncoding());
772 
773             if (!sOption.matchIgnoreAsciiCase(sJavaOption, 0))
774                 arPropStrings[index]= rtl::OString("-D") + sOption;
775             else
776                 arPropStrings[index] = sOption;
777 
778             arOptions[index].optionString = (sal_Char*)arPropStrings[index].getStr();
779             arOptions[index].extraInfo = 0;
780             index ++;
781         }
782 
783         JNIEnv * pMainThreadEnv = 0;
784         javaFrameworkError errcode = JFW_E_NONE;
785         errcode = jfw_startVM(arOptions, index, & m_pJavaVm,
786                                 & pMainThreadEnv);
787 
788         bool bStarted = false;
789         switch (errcode)
790         {
791         case JFW_E_NONE: bStarted = true; break;
792         case JFW_E_NO_SELECT:
793         {
794             // No Java configured. We silenty run the java configuration
795             // Java.
796             javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
797             if (errFind == JFW_E_NONE)
798             {
799                 continue;
800             }
801             else if (errFind == JFW_E_NO_JAVA_FOUND)
802             {
803 
804                 //Warning MessageBox:
805                 //%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task.
806                 //Please install a JRE and restart %PRODUCTNAME.
807                 css::java::JavaNotFoundException exc(
808                     rtl::OUString(
809                         RTL_CONSTASCII_USTRINGPARAM(
810                             "JavaVirtualMachine::getJavaVM failed because"
811                             " No suitable JRE found!")),
812                     static_cast< cppu::OWeakObject * >(this));
813                 askForRetry(css::uno::makeAny(exc));
814                 return css::uno::Any();
815             }
816             else
817             {
818                 //An unexpected error occurred
819                 throw css::uno::RuntimeException(
820                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
821                                       "[JavaVirtualMachine]:An unexpected error occurred"
822                                       " while searching for a Java!")), 0);
823             }
824         }
825         case JFW_E_INVALID_SETTINGS:
826         {
827             //Warning MessageBox:
828             // The %PRODUCTNAME configuration has been changed. Under Tools
829             // - Options - %PRODUCTNAME - Java, select the Java runtime environment
830             // you want to have used by %PRODUCTNAME.
831             css::java::InvalidJavaSettingsException exc(
832                 rtl::OUString(
833                     RTL_CONSTASCII_USTRINGPARAM(
834                         "JavaVirtualMachine::getJavaVM failed because"
835                         " Java settings have changed!")),
836                 static_cast< cppu::OWeakObject * >(this));
837             askForRetry(css::uno::makeAny(exc));
838             return css::uno::Any();
839         }
840         case JFW_E_JAVA_DISABLED:
841         {
842             //QueryBox:
843             //%PRODUCTNAME requires a Java runtime environment (JRE) to perform
844             //this task. However, use of a JRE has been disabled. Do you want to
845             //enable the use of a JRE now?
846             css::java::JavaDisabledException exc(
847                 rtl::OUString(
848                     RTL_CONSTASCII_USTRINGPARAM(
849                         "JavaVirtualMachine::getJavaVM failed because"
850                         " Java is disabled!")),
851                 static_cast< cppu::OWeakObject * >(this));
852             if( ! askForRetry(css::uno::makeAny(exc)))
853                 return css::uno::Any();
854             continue;
855         }
856         case JFW_E_VM_CREATION_FAILED:
857         {
858             //If the creation failed because the JRE has been uninstalled then
859             //we search another one. As long as there is a javaldx, we should
860             //never come into this situation. javaldx checks alway if the JRE
861             //still exist.
862             JavaInfo * pJavaInfo = NULL;
863             if (JFW_E_NONE == jfw_getSelectedJRE(&pJavaInfo))
864             {
865                 sal_Bool bExist = sal_False;
866                 if (JFW_E_NONE == jfw_existJRE(pJavaInfo, &bExist))
867                 {
868                     if (bExist == sal_False
869                         && ! (pJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
870                     {
871                         javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
872                         if (errFind == JFW_E_NONE)
873                         {
874                             continue;
875                         }
876                     }
877                 }
878             }
879 
880             jfw_freeJavaInfo(pJavaInfo);
881             //
882             //Error: %PRODUCTNAME requires a Java
883             //runtime environment (JRE) to perform this task. The selected JRE
884             //is defective. Please select another version or install a new JRE
885             //and select it under Tools - Options - %PRODUCTNAME - Java.
886             css::java::JavaVMCreationFailureException exc(
887                 rtl::OUString(
888                     RTL_CONSTASCII_USTRINGPARAM(
889                         "JavaVirtualMachine::getJavaVM failed because"
890                         " Java is defective!")),
891                 static_cast< cppu::OWeakObject * >(this), 0);
892             askForRetry(css::uno::makeAny(exc));
893             return css::uno::Any();
894         }
895         case JFW_E_RUNNING_JVM:
896         {
897             //This service should make sure that we do not start java twice.
898             OSL_ASSERT(0);
899             break;
900         }
901         case JFW_E_NEED_RESTART:
902         {
903             //Error:
904             //For the selected Java runtime environment to work properly,
905             //%PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.
906             css::java::RestartRequiredException exc(
907                 rtl::OUString(
908                     RTL_CONSTASCII_USTRINGPARAM(
909                         "JavaVirtualMachine::getJavaVM failed because"
910                         "Office must be restarted before Java can be used!")),
911                 static_cast< cppu::OWeakObject * >(this));
912             askForRetry(css::uno::makeAny(exc));
913             return css::uno::Any();
914         }
915         default:
916             //RuntimeException: error is somewhere in the java framework.
917             //An unexpected error occurred
918             throw css::uno::RuntimeException(
919                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
920                                   "[JavaVirtualMachine]:An unexpected error occurred"
921                                   " while starting Java!")), 0);
922         }
923 
924         if (bStarted)
925         {
926             {
927                 DetachCurrentThread detach(m_pJavaVm);
928                     // necessary to make debugging work; this thread will be
929                     // suspended when the destructor of detach returns
930                 m_xVirtualMachine = new jvmaccess::VirtualMachine(
931                     m_pJavaVm, JNI_VERSION_1_2, true, pMainThreadEnv);
932                 setUpUnoVirtualMachine(pMainThreadEnv);
933             }
934             // Listen for changes in the configuration (e.g. proxy settings):
935             // TODO this is done too late; changes to the configuration done
936             // after the above call to initVMConfiguration are lost
937             registerConfigChangesListener();
938 
939             break;
940         }
941     }
942     if (!m_xUnoVirtualMachine.is()) {
943         try {
944             jvmaccess::VirtualMachine::AttachGuard guard(m_xVirtualMachine);
945             setUpUnoVirtualMachine(guard.getEnvironment());
946         } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
947             throw css::uno::RuntimeException(
948                 rtl::OUString(
949                     RTL_CONSTASCII_USTRINGPARAM(
950                         "jvmaccess::VirtualMachine::AttachGuard::"
951                         "CreationException occurred")),
952                 static_cast< cppu::OWeakObject * >(this));
953         }
954     }
955     switch (returnType) {
956     default: // RETURN_JAVAVM
957         if (m_pJavaVm == 0) {
958             throw css::uno::RuntimeException(
959                 rtl::OUString(
960                     RTL_CONSTASCII_USTRINGPARAM(
961                         "JavaVirtualMachine service was initialized in a way"
962                         " that the requested JavaVM pointer is not available")),
963                 static_cast< cppu::OWeakObject * >(this));
964         }
965         return css::uno::makeAny(reinterpret_cast< sal_IntPtr >(m_pJavaVm));
966     case RETURN_VIRTUALMACHINE:
967         OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
968         return css::uno::makeAny(
969             reinterpret_cast< sal_Int64 >(
970                 m_xUnoVirtualMachine->getVirtualMachine().get()));
971     case RETURN_UNOVIRTUALMACHINE:
972         OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
973         return css::uno::makeAny(
974             reinterpret_cast< sal_Int64 >(m_xUnoVirtualMachine.get()));
975     }
976 }
977 
isVMStarted()978 sal_Bool SAL_CALL JavaVirtualMachine::isVMStarted()
979 {
980     osl::MutexGuard aGuard(*this);
981     if (m_bDisposed)
982         throw css::lang::DisposedException(
983             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
984     return m_xUnoVirtualMachine.is();
985 }
986 
isVMEnabled()987 sal_Bool SAL_CALL JavaVirtualMachine::isVMEnabled()
988 {
989     {
990         osl::MutexGuard aGuard(*this);
991         if (m_bDisposed)
992             throw css::lang::DisposedException(
993                 rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
994     }
995 //    stoc_javavm::JVM aJvm;
996 //    initVMConfiguration(&aJvm, m_xContext->getServiceManager(), m_xContext);
997 //    return aJvm.isEnabled();
998     //ToDo
999     sal_Bool bEnabled = sal_False;
1000     if (jfw_getEnabled( & bEnabled) != JFW_E_NONE)
1001         throw css::uno::RuntimeException();
1002     return bEnabled;
1003 }
1004 
isThreadAttached()1005 sal_Bool SAL_CALL JavaVirtualMachine::isThreadAttached()
1006 {
1007     osl::MutexGuard aGuard(*this);
1008     if (m_bDisposed)
1009         throw css::lang::DisposedException(
1010             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
1011     // TODO isThreadAttached only returns true if the thread was attached via
1012     // registerThread:
1013     GuardStack * pStack
1014         = static_cast< GuardStack * >(m_aAttachGuards.getData());
1015     return pStack != 0 && !pStack->empty();
1016 }
1017 
registerThread()1018 void SAL_CALL JavaVirtualMachine::registerThread()
1019 {
1020     osl::MutexGuard aGuard(*this);
1021     if (m_bDisposed)
1022         throw css::lang::DisposedException(
1023             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
1024     if (!m_xUnoVirtualMachine.is())
1025         throw css::uno::RuntimeException(
1026             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1027                               "JavaVirtualMachine::registerThread:"
1028                               " null VirtualMachine")),
1029             static_cast< cppu::OWeakObject * >(this));
1030     GuardStack * pStack
1031         = static_cast< GuardStack * >(m_aAttachGuards.getData());
1032     if (pStack == 0)
1033     {
1034         pStack = new GuardStack;
1035         m_aAttachGuards.setData(pStack);
1036     }
1037     try
1038     {
1039         pStack->push(
1040             new jvmaccess::VirtualMachine::AttachGuard(
1041                 m_xUnoVirtualMachine->getVirtualMachine()));
1042     }
1043     catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1044     {
1045         throw css::uno::RuntimeException(
1046             rtl::OUString(
1047                 RTL_CONSTASCII_USTRINGPARAM(
1048                     "JavaVirtualMachine::registerThread: jvmaccess::"
1049                     "VirtualMachine::AttachGuard::CreationException")),
1050             static_cast< cppu::OWeakObject * >(this));
1051     }
1052 }
1053 
revokeThread()1054 void SAL_CALL JavaVirtualMachine::revokeThread()
1055 {
1056     osl::MutexGuard aGuard(*this);
1057     if (m_bDisposed)
1058         throw css::lang::DisposedException(
1059             rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
1060     if (!m_xUnoVirtualMachine.is())
1061         throw css::uno::RuntimeException(
1062             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1063                               "JavaVirtualMachine::revokeThread:"
1064                               " null VirtualMachine")),
1065             static_cast< cppu::OWeakObject * >(this));
1066     GuardStack * pStack
1067         = static_cast< GuardStack * >(m_aAttachGuards.getData());
1068     if (pStack == 0 || pStack->empty())
1069         throw css::uno::RuntimeException(
1070             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1071                               "JavaVirtualMachine::revokeThread:"
1072                               " no matching registerThread")),
1073             static_cast< cppu::OWeakObject * >(this));
1074     delete pStack->top();
1075     pStack->pop();
1076 }
1077 
1078 void SAL_CALL
disposing(css::lang::EventObject const & rSource)1079 JavaVirtualMachine::disposing(css::lang::EventObject const & rSource)
1080 {
1081     osl::MutexGuard aGuard(*this);
1082     if (rSource.Source == m_xInetConfiguration)
1083         m_xInetConfiguration.clear();
1084     if (rSource.Source == m_xJavaConfiguration)
1085         m_xJavaConfiguration.clear();
1086 }
1087 
elementInserted(css::container::ContainerEvent const &)1088 void SAL_CALL JavaVirtualMachine::elementInserted(
1089     css::container::ContainerEvent const &)
1090 {}
1091 
elementRemoved(css::container::ContainerEvent const &)1092 void SAL_CALL JavaVirtualMachine::elementRemoved(
1093     css::container::ContainerEvent const &)
1094 {}
1095 
1096 // If a user changes the setting, for example for proxy settings, then this
1097 // function will be called from the configuration manager.  Even if the .xml
1098 // file does not contain an entry yet and that entry has to be inserted, this
1099 // function will be called.  We call java.lang.System.setProperty for the new
1100 // values.
elementReplaced(css::container::ContainerEvent const & rEvent)1101 void SAL_CALL JavaVirtualMachine::elementReplaced(
1102     css::container::ContainerEvent const & rEvent)
1103 {
1104     // TODO Using the new value stored in rEvent is wrong here.  If two threads
1105     // receive different elementReplaced calls in quick succession, it is
1106     // unspecified which changes the JVM's system properties last.  A correct
1107     // solution must atomically (i.e., protected by a mutex) read the latest
1108     // value from the configuration and set it as a system property at the JVM.
1109 
1110     rtl::OUString aAccessor;
1111     rEvent.Accessor >>= aAccessor;
1112     rtl::OUString aPropertyName;
1113     rtl::OUString aPropertyName2;
1114     rtl::OUString aPropertyValue;
1115     bool bSecurityChanged = false;
1116     if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ooInetProxyType")))
1117     {
1118         // Proxy none, manually
1119         sal_Int32 value = 0;
1120         rEvent.Element >>= value;
1121         setINetSettingsInVM(value != 0);
1122         return;
1123     }
1124     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1125                                         "ooInetHTTPProxyName")))
1126     {
1127         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1128                                           "http.proxyHost"));
1129         rEvent.Element >>= aPropertyValue;
1130     }
1131     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1132                                         "ooInetHTTPProxyPort")))
1133     {
1134         aPropertyName
1135             = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort"));
1136         sal_Int32 n = 0;
1137         rEvent.Element >>= n;
1138         aPropertyValue = rtl::OUString::valueOf(n);
1139     }
1140     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1141                                         "ooInetHTTPSProxyName")))
1142     {
1143         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1144                                           "https.proxyHost"));
1145         rEvent.Element >>= aPropertyValue;
1146     }
1147     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1148                                         "ooInetHTTPSProxyPort")))
1149     {
1150         aPropertyName
1151             = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyPort"));
1152         sal_Int32 n = 0;
1153         rEvent.Element >>= n;
1154         aPropertyValue = rtl::OUString::valueOf(n);
1155     }
1156     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1157                                         "ooInetFTPProxyName")))
1158     {
1159         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1160                                           "ftp.proxyHost"));
1161         rEvent.Element >>= aPropertyValue;
1162     }
1163     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1164                                         "ooInetFTPProxyPort")))
1165     {
1166         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1167                                           "ftp.proxyPort"));
1168         sal_Int32 n = 0;
1169         rEvent.Element >>= n;
1170         aPropertyValue = rtl::OUString::valueOf(n);
1171     }
1172     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
1173                                         "ooInetNoProxy")))
1174     {
1175         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1176                                           "http.nonProxyHosts"));
1177         aPropertyName2 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1178                                            "ftp.nonProxyHosts"));
1179         rEvent.Element >>= aPropertyValue;
1180         aPropertyValue = aPropertyValue.replace(';', '|');
1181     }
1182     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("NetAccess")))
1183     {
1184         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1185                                           "appletviewer.security.mode"));
1186         sal_Int32 n = 0;
1187         if (rEvent.Element >>= n)
1188             switch (n)
1189             {
1190             case 0:
1191                 aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1192                                                    "host"));
1193                 break;
1194             case 1:
1195                 aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1196                                                    "unrestricted"));
1197                 break;
1198             case 3:
1199                 aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1200                                                    "none"));
1201                 break;
1202             }
1203         else
1204             return;
1205         bSecurityChanged = true;
1206     }
1207     else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Security")))
1208     {
1209         aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1210                                           "stardiv.security.disableSecurity"));
1211         sal_Bool b = sal_Bool();
1212         if (rEvent.Element >>= b)
1213             if (b)
1214                 aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1215                                                    "false"));
1216             else
1217                 aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1218                                                    "true"));
1219         else
1220             return;
1221         bSecurityChanged = true;
1222     }
1223     else
1224         return;
1225 
1226     rtl::Reference< jvmaccess::VirtualMachine > xVirtualMachine;
1227     {
1228         osl::MutexGuard aGuard(*this);
1229         if (m_xUnoVirtualMachine.is()) {
1230             xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
1231         }
1232     }
1233     if (xVirtualMachine.is())
1234     {
1235         try
1236         {
1237             jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
1238                 xVirtualMachine);
1239             JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1240 
1241             // call java.lang.System.setProperty
1242             // String setProperty( String key, String value)
1243             jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1244             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/lang/System")), 0);
1245             jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1246             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.setProperty")), 0);
1247 
1248             jstring jsPropName= pJNIEnv->NewString( aPropertyName.getStr(), aPropertyName.getLength());
1249             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1250 
1251             // remove the property if it does not have a value ( user left the dialog field empty)
1252             // or if the port is set to 0
1253             aPropertyValue= aPropertyValue.trim();
1254             if(
1255                aPropertyValue.getLength() == 0 ||
1256                (
1257                 (
1258                  aPropertyName.equals( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort"))) ||
1259                  aPropertyName.equals( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort"))) /*||
1260                  aPropertyName.equals( OUString( RTL_CONSTASCII_USTRINGPARAM("socksProxyPort")))*/
1261                 ) &&
1262                 aPropertyValue.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0")))
1263                )
1264               )
1265             {
1266                 // call java.lang.System.getProperties
1267                 jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1268                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getProperties")), 0);
1269                 jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1270                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.getProperties")), 0);
1271                 // call java.util.Properties.remove
1272                 jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1273                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/util/Properties")), 0);
1274                 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1275                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.util.Properties.remove")), 0);
1276                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName);
1277 
1278                 // special calse for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1279                 // has a value for two java properties
1280                 if (aPropertyName2.getLength() > 0)
1281                 {
1282                     jstring jsPropName2= pJNIEnv->NewString( aPropertyName2.getStr(), aPropertyName2.getLength());
1283                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1284                     pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName2);
1285                 }
1286             }
1287             else
1288             {
1289                 // Change the Value of the property
1290                 jstring jsPropValue= pJNIEnv->NewString( aPropertyValue.getStr(), aPropertyValue.getLength());
1291                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1292                 pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName, jsPropValue);
1293                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1294 
1295                 // special calse for ftp.nonProxyHosts and http.nonProxyHosts. The office only
1296                 // has a value for two java properties
1297                 if (aPropertyName2.getLength() > 0)
1298                 {
1299                     jstring jsPropName2= pJNIEnv->NewString( aPropertyName2.getStr(), aPropertyName2.getLength());
1300                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1301                     jsPropValue= pJNIEnv->NewString( aPropertyValue.getStr(), aPropertyValue.getLength());
1302                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1303                     pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName2, jsPropValue);
1304                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1305                 }
1306             }
1307 
1308             // If the settings for Security and NetAccess changed then we have to notify the SandboxSecurity
1309             // SecurityManager
1310             // call System.getSecurityManager()
1311             if (bSecurityChanged)
1312             {
1313                 jmethodID jmGetSecur= pJNIEnv->GetStaticMethodID( jcSystem,"getSecurityManager","()Ljava/lang/SecurityManager;");
1314                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getSecurityManager")), 0);
1315                 jobject joSecur= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetSecur);
1316                 if (joSecur != 0)
1317                 {
1318                     // Make sure the SecurityManager is our SandboxSecurity
1319                     // FindClass("com.sun.star.lib.sandbox.SandboxSecurityManager" only worked at the first time
1320                     // this code was executed. Maybe it is a security feature. However, all attempts to debug the
1321                     // SandboxSecurity class (maybe the VM invokes checkPackageAccess)  failed.
1322 //                  jclass jcSandboxSec= pJNIEnv->FindClass("com.sun.star.lib.sandbox.SandboxSecurity");
1323 //                  if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUSTR("JNI:FindClass com.sun.star.lib.sandbox.SandboxSecurity"), Reference<XInterface>());
1324 //                  jboolean bIsSand= pJNIEnv->IsInstanceOf( joSecur, jcSandboxSec);
1325                     // The SecurityManagers class Name must be com.sun.star.lib.sandbox.SandboxSecurity
1326                     jclass jcSec= pJNIEnv->GetObjectClass( joSecur);
1327                     jclass jcClass= pJNIEnv->FindClass("java/lang/Class");
1328                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java.lang.Class")), 0);
1329                     jmethodID jmName= pJNIEnv->GetMethodID( jcClass,"getName","()Ljava/lang/String;");
1330                     if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.lang.Class.getName")), 0);
1331                     jstring jsClass= (jstring) pJNIEnv->CallObjectMethod( jcSec, jmName);
1332                     const jchar* jcharName= pJNIEnv->GetStringChars( jsClass, NULL);
1333                     rtl::OUString sName( jcharName);
1334                     jboolean bIsSandbox;
1335                     if (sName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lib.sandbox.SandboxSecurity")))
1336                         bIsSandbox= JNI_TRUE;
1337                     else
1338                         bIsSandbox= JNI_FALSE;
1339                     pJNIEnv->ReleaseStringChars( jsClass, jcharName);
1340 
1341                     if (bIsSandbox == JNI_TRUE)
1342                     {
1343                         // call SandboxSecurity.reset
1344                         jmethodID jmReset= pJNIEnv->GetMethodID( jcSec,"reset","()V");
1345                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID com.sun.star.lib.sandbox.SandboxSecurity.reset")), 0);
1346                         pJNIEnv->CallVoidMethod( joSecur, jmReset);
1347                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallVoidMethod com.sun.star.lib.sandbox.SandboxSecurity.reset")), 0);
1348                     }
1349                 }
1350             }
1351         }
1352         catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1353         {
1354             throw css::uno::RuntimeException(
1355                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1356                                   "jvmaccess::VirtualMachine::AttachGuard::"
1357                                   "CreationException")),
1358                 0);
1359         }
1360     }
1361 }
1362 
~JavaVirtualMachine()1363 JavaVirtualMachine::~JavaVirtualMachine()
1364 {
1365     if (m_xInetConfiguration.is())
1366         // We should never get here, but just in case...
1367         try
1368         {
1369             m_xInetConfiguration->removeContainerListener(this);
1370         }
1371         catch (css::uno::Exception &)
1372         {
1373             OSL_ENSURE(false, "com.sun.star.uno.Exception caught");
1374         }
1375     if (m_xJavaConfiguration.is())
1376         // We should never get here, but just in case...
1377         try
1378         {
1379             m_xJavaConfiguration->removeContainerListener(this);
1380         }
1381         catch (css::uno::Exception &)
1382         {
1383             OSL_ENSURE(false, "com.sun.star.uno.Exception caught");
1384         }
1385 }
1386 
disposing()1387 void SAL_CALL JavaVirtualMachine::disposing()
1388 {
1389     css::uno::Reference< css::container::XContainer > xContainer1;
1390     css::uno::Reference< css::container::XContainer > xContainer2;
1391     {
1392         osl::MutexGuard aGuard(*this);
1393         m_bDisposed = true;
1394         xContainer1 = m_xInetConfiguration;
1395         m_xInetConfiguration.clear();
1396         xContainer2 = m_xJavaConfiguration;
1397         m_xJavaConfiguration.clear();
1398     }
1399     if (xContainer1.is())
1400         xContainer1->removeContainerListener(this);
1401     if (xContainer2.is())
1402         xContainer2->removeContainerListener(this);
1403 }
1404 
1405 /*We listen to changes in the configuration. For example, the user changes the proxy
1406   settings in the options dialog (menu tools). Then we are notified of this change and
1407   if the java vm is already running we change the properties (System.lang.System.setProperties)
1408   through JNI.
1409   To receive notifications this class implements XContainerListener.
1410 */
registerConfigChangesListener()1411 void JavaVirtualMachine::registerConfigChangesListener()
1412 {
1413     try
1414     {
1415         css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
1416             m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1417                 "com.sun.star.configuration.ConfigurationProvider")), m_xContext), css::uno::UNO_QUERY);
1418 
1419         if (xConfigProvider.is())
1420         {
1421             // We register this instance as listener to changes in org.openoffice.Inet/Settings
1422             // arguments for ConfigurationAccess
1423             css::uno::Sequence< css::uno::Any > aArguments(2);
1424             aArguments[0] <<= css::beans::PropertyValue(
1425                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")),
1426                 0,
1427                 css::uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet/Settings"))),
1428                 css::beans::PropertyState_DIRECT_VALUE);
1429             // depth: -1 means unlimited
1430             aArguments[1] <<= css::beans::PropertyValue(
1431                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("depth")),
1432                 0,
1433                 css::uno::makeAny( (sal_Int32)-1),
1434                 css::beans::PropertyState_DIRECT_VALUE);
1435 
1436             m_xInetConfiguration
1437                 = css::uno::Reference< css::container::XContainer >(
1438                     xConfigProvider->createInstanceWithArguments(
1439                         rtl::OUString(
1440                             RTL_CONSTASCII_USTRINGPARAM(
1441                              "com.sun.star.configuration.ConfigurationAccess")),
1442                         aArguments),
1443                     css::uno::UNO_QUERY);
1444 
1445             if (m_xInetConfiguration.is())
1446                 m_xInetConfiguration->addContainerListener(this);
1447 
1448             // now register as listener to changes in org.openoffice.Java/VirtualMachine
1449             css::uno::Sequence< css::uno::Any > aArguments2(2);
1450             aArguments2[0] <<= css::beans::PropertyValue(
1451                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")),
1452                 0,
1453                 css::uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Java/VirtualMachine"))),
1454                 css::beans::PropertyState_DIRECT_VALUE);
1455             // depth: -1 means unlimited
1456             aArguments2[1] <<= css::beans::PropertyValue(
1457                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("depth")),
1458                 0,
1459                 css::uno::makeAny( (sal_Int32)-1),
1460                 css::beans::PropertyState_DIRECT_VALUE);
1461 
1462             m_xJavaConfiguration
1463                 = css::uno::Reference< css::container::XContainer >(
1464                     xConfigProvider->createInstanceWithArguments(
1465                         rtl::OUString(
1466                             RTL_CONSTASCII_USTRINGPARAM(
1467                              "com.sun.star.configuration.ConfigurationAccess")),
1468                         aArguments2),
1469                     css::uno::UNO_QUERY);
1470 
1471             if (m_xJavaConfiguration.is())
1472                 m_xJavaConfiguration->addContainerListener(this);
1473         }
1474     }catch( css::uno::Exception & e)
1475     {
1476 #if OSL_DEBUG_LEVEL > 1
1477         rtl::OString message = rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
1478         OSL_TRACE("javavm.cxx: could not set up listener for Configuration because of >%s<", message.getStr());
1479 #else
1480         (void) e; // unused
1481 #endif
1482     }
1483 }
1484 
1485 // param true: all Inet setting are set as Java Properties on a live VM.
1486 // false: the Java net properties are set to empty value.
setINetSettingsInVM(bool set_reset)1487 void JavaVirtualMachine::setINetSettingsInVM(bool set_reset)
1488 {
1489     osl::MutexGuard aGuard(*this);
1490     try
1491     {
1492         if (m_xUnoVirtualMachine.is())
1493         {
1494             jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
1495                 m_xUnoVirtualMachine->getVirtualMachine());
1496             JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
1497 
1498             // The Java Properties
1499             rtl::OUString sFtpProxyHost(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyHost") );
1500             rtl::OUString sFtpProxyPort(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort") );
1501             rtl::OUString sFtpNonProxyHosts (RTL_CONSTASCII_USTRINGPARAM("ftp.nonProxyHosts"));
1502             rtl::OUString sHttpProxyHost(RTL_CONSTASCII_USTRINGPARAM("http.proxyHost") );
1503             rtl::OUString sHttpProxyPort(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort") );
1504             rtl::OUString sHttpNonProxyHosts(RTL_CONSTASCII_USTRINGPARAM("http.nonProxyHosts"));
1505 
1506             // creat Java Properties as JNI strings
1507             jstring jsFtpProxyHost= pJNIEnv->NewString( sFtpProxyHost.getStr(), sFtpProxyHost.getLength());
1508             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1509             jstring jsFtpProxyPort= pJNIEnv->NewString( sFtpProxyPort.getStr(), sFtpProxyPort.getLength());
1510             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1511             jstring jsFtpNonProxyHosts= pJNIEnv->NewString( sFtpNonProxyHosts.getStr(), sFtpNonProxyHosts.getLength());
1512             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1513             jstring jsHttpProxyHost= pJNIEnv->NewString( sHttpProxyHost.getStr(), sHttpProxyHost.getLength());
1514             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1515             jstring jsHttpProxyPort= pJNIEnv->NewString( sHttpProxyPort.getStr(), sHttpProxyPort.getLength());
1516             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1517             jstring jsHttpNonProxyHosts= pJNIEnv->NewString( sHttpNonProxyHosts.getStr(), sHttpNonProxyHosts.getLength());
1518             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1519 
1520             // prepare java.lang.System.setProperty
1521             jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
1522             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/lang/System")), 0);
1523             jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
1524             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.setProperty")), 0);
1525 
1526             // call java.lang.System.getProperties
1527             jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
1528             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getProperties")), 0);
1529             jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
1530             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.getProperties")), 0);
1531             // prepare java.util.Properties.remove
1532             jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
1533             if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/util/Properties")), 0);
1534 
1535             if (set_reset)
1536             {
1537                 // Set all network properties with the VM
1538                 JVM jvm;
1539                 getINetPropsFromConfig( &jvm, m_xContext->getServiceManager(), m_xContext);
1540                 const ::std::vector< rtl::OUString> & Props = jvm.getProperties();
1541                 typedef ::std::vector< rtl::OUString >::const_iterator C_IT;
1542 
1543                 for( C_IT i= Props.begin(); i != Props.end(); i++)
1544                 {
1545                     rtl::OUString prop= *i;
1546                     sal_Int32 index= prop.indexOf( (sal_Unicode)'=');
1547                     rtl::OUString propName= prop.copy( 0, index);
1548                     rtl::OUString propValue= prop.copy( index + 1);
1549 
1550                     if( propName.equals( sFtpProxyHost))
1551                     {
1552                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1553                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1554                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyHost, jsVal);
1555                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1556                     }
1557                     else if( propName.equals( sFtpProxyPort))
1558                     {
1559                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1560                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1561                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyPort, jsVal);
1562                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1563                     }
1564                     else if( propName.equals( sFtpNonProxyHosts))
1565                     {
1566                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1567                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1568                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpNonProxyHosts, jsVal);
1569                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1570                     }
1571                     else if( propName.equals( sHttpProxyHost))
1572                     {
1573                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1574                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1575                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyHost, jsVal);
1576                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1577                     }
1578                     else if( propName.equals( sHttpProxyPort))
1579                     {
1580                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1581                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1582                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyPort, jsVal);
1583                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1584                     }
1585                     else if( propName.equals( sHttpNonProxyHosts))
1586                     {
1587                         jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
1588                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
1589                         pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpNonProxyHosts, jsVal);
1590                         if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
1591                     }
1592                 }
1593             }
1594             else
1595             {
1596                 // call java.util.Properties.remove
1597                 jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
1598                 if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.util.Property.remove")), 0);
1599                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyHost);
1600                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyPort);
1601                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpNonProxyHosts);
1602                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyHost);
1603                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyPort);
1604                 pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpNonProxyHosts);
1605             }
1606         }
1607     }
1608     catch (css::uno::RuntimeException &)
1609     {
1610         OSL_ENSURE(false, "RuntimeException");
1611     }
1612     catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
1613     {
1614         OSL_ENSURE(false,
1615                    "jvmaccess::VirtualMachine::AttachGuard::CreationException");
1616     }
1617 }
1618 
setUpUnoVirtualMachine(JNIEnv * environment)1619 void JavaVirtualMachine::setUpUnoVirtualMachine(JNIEnv * environment) {
1620     css::uno::Reference< css::util::XMacroExpander > exp;
1621     if (!(m_xContext->getValueByName(
1622               rtl::OUString(
1623                   RTL_CONSTASCII_USTRINGPARAM(
1624                       "/singletons/com.sun.star.util.theMacroExpander")))
1625           >>= exp)
1626         || !exp.is())
1627     {
1628         throw css::uno::RuntimeException(
1629             rtl::OUString(
1630                 RTL_CONSTASCII_USTRINGPARAM(
1631                     "component context fails to supply singleton"
1632                     " com.sun.star.util.theMacroExpander of type"
1633                     " com.sun.star.util.XMacroExpander")),
1634             m_xContext);
1635     }
1636     rtl::OUString baseUrl;
1637     try {
1638         baseUrl = exp->expandMacros(
1639             rtl::OUString(
1640                 RTL_CONSTASCII_USTRINGPARAM("$URE_INTERNAL_JAVA_DIR/")));
1641     } catch (css::lang::IllegalArgumentException &) {
1642         throw css::uno::RuntimeException(
1643             rtl::OUString(
1644                 RTL_CONSTASCII_USTRINGPARAM(
1645                     "com::sun::star::lang::IllegalArgumentException")),
1646             static_cast< cppu::OWeakObject * >(this));
1647     }
1648     rtl::OUString classPath;
1649     try {
1650         classPath = exp->expandMacros(
1651             rtl::OUString(
1652                 RTL_CONSTASCII_USTRINGPARAM("$URE_INTERNAL_JAVA_CLASSPATH")));
1653     } catch (css::lang::IllegalArgumentException &) {}
1654     jclass class_URLClassLoader = environment->FindClass(
1655         "java/net/URLClassLoader");
1656     if (class_URLClassLoader == 0) {
1657         handleJniException(environment);
1658     }
1659     jmethodID ctor_URLClassLoader = environment->GetMethodID(
1660         class_URLClassLoader, "<init>", "([Ljava/net/URL;)V");
1661     if (ctor_URLClassLoader == 0) {
1662         handleJniException(environment);
1663     }
1664     jclass class_URL = environment->FindClass("java/net/URL");
1665     if (class_URL == 0) {
1666         handleJniException(environment);
1667     }
1668     jmethodID ctor_URL_1 = environment->GetMethodID(
1669         class_URL, "<init>", "(Ljava/lang/String;)V");
1670     if (ctor_URL_1 == 0) {
1671         handleJniException(environment);
1672     }
1673     jvalue args[3];
1674     args[0].l = environment->NewString(
1675         static_cast< jchar const * >(baseUrl.getStr()),
1676         static_cast< jsize >(baseUrl.getLength()));
1677     if (args[0].l == 0) {
1678         handleJniException(environment);
1679     }
1680     jobject base = environment->NewObjectA(class_URL, ctor_URL_1, args);
1681     if (base == 0) {
1682         handleJniException(environment);
1683     }
1684     jmethodID ctor_URL_2 = environment->GetMethodID(
1685         class_URL, "<init>", "(Ljava/net/URL;Ljava/lang/String;)V");
1686     if (ctor_URL_2 == 0) {
1687         handleJniException(environment);
1688     }
1689     jobjectArray classpath = jvmaccess::ClassPath::translateToUrls(
1690         m_xContext, environment, classPath);
1691     if (classpath == 0) {
1692         handleJniException(environment);
1693     }
1694     args[0].l = base;
1695     args[1].l = environment->NewStringUTF("unoloader.jar");
1696     if (args[1].l == 0) {
1697         handleJniException(environment);
1698     }
1699     args[0].l = environment->NewObjectA(class_URL, ctor_URL_2, args);
1700     if (args[0].l == 0) {
1701         handleJniException(environment);
1702     }
1703     args[0].l = environment->NewObjectArray(1, class_URL, args[0].l);
1704     if (args[0].l == 0) {
1705         handleJniException(environment);
1706     }
1707     jobject cl1 = environment->NewObjectA(
1708         class_URLClassLoader, ctor_URLClassLoader, args);
1709     if (cl1 == 0) {
1710         handleJniException(environment);
1711     }
1712     jmethodID method_loadClass = environment->GetMethodID(
1713         class_URLClassLoader, "loadClass",
1714         "(Ljava/lang/String;)Ljava/lang/Class;");
1715     if (method_loadClass == 0) {
1716         handleJniException(environment);
1717     }
1718     args[0].l = environment->NewStringUTF(
1719         "com.sun.star.lib.unoloader.UnoClassLoader");
1720     if (args[0].l == 0) {
1721         handleJniException(environment);
1722     }
1723     jclass class_UnoClassLoader = static_cast< jclass >(
1724         environment->CallObjectMethodA(cl1, method_loadClass, args));
1725     if (class_UnoClassLoader == 0) {
1726         handleJniException(environment);
1727     }
1728     jmethodID ctor_UnoClassLoader = environment->GetMethodID(
1729         class_UnoClassLoader, "<init>",
1730         "(Ljava/net/URL;[Ljava/net/URL;Ljava/lang/ClassLoader;)V");
1731     if (ctor_UnoClassLoader == 0) {
1732         handleJniException(environment);
1733     }
1734     args[0].l = base;
1735     args[1].l = classpath;
1736     args[2].l = cl1;
1737     jobject cl2 = environment->NewObjectA(
1738         class_UnoClassLoader, ctor_UnoClassLoader, args);
1739     if (cl2 == 0) {
1740         handleJniException(environment);
1741     }
1742     try {
1743         m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(
1744             m_xVirtualMachine, cl2);
1745     } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
1746         throw css::uno::RuntimeException(
1747             rtl::OUString(
1748                 RTL_CONSTASCII_USTRINGPARAM(
1749                     "jvmaccess::UnoVirtualMachine::CreationException")),
1750             static_cast< cppu::OWeakObject * >(this));
1751     }
1752 }
1753 
handleJniException(JNIEnv * environment)1754 void JavaVirtualMachine::handleJniException(JNIEnv * environment) {
1755     environment->ExceptionClear();
1756     throw css::uno::RuntimeException(
1757         rtl::OUString(
1758             RTL_CONSTASCII_USTRINGPARAM("JNI exception occurred")),
1759         static_cast< cppu::OWeakObject * >(this));
1760 }
1761