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