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