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