Files
libreoffice/stoc/source/javavm/javavm.cxx

900 lines
32 KiB
C++
Raw Normal View History

2000-09-18 14:29:57 +00:00
/*************************************************************************
*
* $RCSfile: javavm.cxx,v $
*
2001-10-17 14:52:51 +00:00
* $Revision: 1.20 $
2000-09-18 14:29:57 +00:00
*
2001-10-17 14:52:51 +00:00
* last change: $Author: jl $ $Date: 2001-10-17 15:52:51 $
2000-09-18 14:29:57 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifdef UNX
#include <signal.h>
#endif
2000-09-18 14:29:57 +00:00
#include <time.h>
#include <osl/diagnose.h>
#include <osl/file.hxx>
2000-09-18 14:29:57 +00:00
#include <rtl/process.h>
2000-09-18 14:29:57 +00:00
#ifndef _OSL_MODULE_HXX_
#include <osl/module.hxx>
#endif
2000-09-18 14:29:57 +00:00
#ifndef _OSL_CONDITN_HXX_
#include <osl/conditn.hxx>
#endif
2000-09-18 14:29:57 +00:00
2001-03-16 15:24:27 +00:00
#ifndef _THREAD_HXX_
#include <osl/thread.hxx>
#endif
#include <uno/environment.h>
2000-09-18 14:29:57 +00:00
#include <cppuhelper/factory.hxx>
#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/implbase3.hxx>
#include <com/sun/star/uno/Sequence.hxx>
2000-09-18 14:29:57 +00:00
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/java/XJavaVM.hpp>
#include <com/sun/star/java/XJavaThreadRegister_11.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/registry/InvalidRegistryException.hpp>
#include <bridges/java/jvmcontext.hxx>
2000-09-18 14:29:57 +00:00
#include "jvmargs.hxx"
// Properties of the javavm can be put
// as a komma separated list in this
// environment variable
#define PROPERTIES_ENV "OO_JAVA_PROPERTIES"
2000-09-18 14:29:57 +00:00
#ifdef UNIX
#define INI_FILE "javarc"
2001-03-09 03:35:21 +00:00
#ifdef MACOSX
#define DEF_JAVALIB "JavaVM.framework"
#else
#define DEF_JAVALIB "libjvm.so"
2001-03-09 03:35:21 +00:00
#endif
2000-09-18 14:29:57 +00:00
#define TIMEZONE "MEZ"
2000-09-18 14:29:57 +00:00
#else
#define INI_FILE "java.ini"
#define DEF_JAVALIB "javai.dll"
2000-09-18 14:29:57 +00:00
#define TIMEZONE "MET"
2000-09-18 14:29:57 +00:00
#endif
2000-09-18 14:29:57 +00:00
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::java;
using namespace com::sun::star::registry;
2000-09-18 14:29:57 +00:00
using namespace rtl;
using namespace cppu;
using namespace osl;
2000-09-18 14:29:57 +00:00
namespace stoc_javavm {
static Sequence< OUString > javavm_getSupportedServiceNames()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(1);
seqNames.getArray()[0] = OUString(
RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.java.JavaVirtualMachine") );
pNames = &seqNames;
}
}
return *pNames;
}
static OUString javavm_getImplementationName()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName(
RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.JavaVirtualMachine" ) );
pImplName = &implName;
}
}
return *pImplName;
}
static jint JNICALL vm_vfprintf( FILE *fp, const char *format, va_list args ) {
#ifdef DEBUG
char buff[1024];
2000-09-18 14:29:57 +00:00
vsprintf( buff, format, args );
2000-09-18 14:29:57 +00:00
OSL_TRACE("%s", buff);
return strlen(buff);
#else
return 0;
#endif
2000-09-18 14:29:57 +00:00
}
static void JNICALL vm_exit(jint code) {
OSL_TRACE("vm_exit: %d\n", code);
2000-09-18 14:29:57 +00:00
}
static void JNICALL vm_abort() {
OSL_TRACE("vm_abort\n");
2001-01-31 15:43:39 +00:00
abort();
2000-09-18 14:29:57 +00:00
}
typedef ::std::hash_map<sal_uInt32, sal_uInt32> UINT32_UINT32_HashMap;
2000-09-18 14:29:57 +00:00
class JavaVirtualMachine_Impl;
2000-09-18 14:29:57 +00:00
2001-03-16 15:24:27 +00:00
class OCreatorThread : public Thread {
JavaVirtualMachine_Impl * _pJavaVirtualMachine_Impl;
JavaVM * _pJVM;
2000-09-18 14:29:57 +00:00
Condition _start_Condition;
Condition _wait_Condition;
2000-09-18 14:29:57 +00:00
JVM _jvm;
RuntimeException _runtimeException;
2000-09-18 14:29:57 +00:00
protected:
virtual void SAL_CALL run() throw();
2000-09-18 14:29:57 +00:00
public:
OCreatorThread(JavaVirtualMachine_Impl * pJavaVirtualMachine_Impl) throw();
JavaVM * createJavaVM(const JVM & jvm) throw (RuntimeException);
void disposeJavaVM() throw();
2000-09-18 14:29:57 +00:00
};
2000-09-18 14:29:57 +00:00
class JavaVirtualMachine_Impl : public WeakImplHelper3<XJavaVM, XJavaThreadRegister_11, XServiceInfo> {
Mutex _Mutex;
2000-09-18 14:29:57 +00:00
OCreatorThread _creatorThread;
2000-09-18 14:29:57 +00:00
uno_Environment * _pJava_environment;
JavaVMContext * _pVMContext;
2000-09-18 14:29:57 +00:00
Reference<XComponentContext> _xCtx;
Reference<XMultiComponentFactory > _xSMgr;
2000-09-18 14:29:57 +00:00
Module _javaLib;
2000-09-18 14:29:57 +00:00
public:
2000-12-19 09:20:57 +00:00
OUString _error;
2000-09-18 14:29:57 +00:00
JavaVirtualMachine_Impl(const Reference<XComponentContext> & xCtx) throw();
~JavaVirtualMachine_Impl() throw();
2000-09-18 14:29:57 +00:00
// XJavaVM
virtual Any SAL_CALL getJavaVM(const Sequence<sal_Int8> & processID) throw(RuntimeException);
virtual sal_Bool SAL_CALL isVMStarted(void) throw( RuntimeException);
virtual sal_Bool SAL_CALL isVMEnabled(void) throw( RuntimeException);
2000-09-18 14:29:57 +00:00
// XJavaThreadRegister_11
virtual sal_Bool SAL_CALL isThreadAttached(void) throw(RuntimeException);
virtual void SAL_CALL registerThread(void) throw(RuntimeException);
virtual void SAL_CALL revokeThread(void) throw(RuntimeException);
2000-09-18 14:29:57 +00:00
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
virtual Sequence<OUString> SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
2000-09-18 14:29:57 +00:00
JavaVM * createJavaVM(const JVM & jvm) throw(RuntimeException);
void disposeJavaVM() throw();
};
2000-09-18 14:29:57 +00:00
OCreatorThread::OCreatorThread(JavaVirtualMachine_Impl * pJavaVirtualMachine_Impl) throw()
: _pJVM(NULL)
2000-09-18 14:29:57 +00:00
{
_pJavaVirtualMachine_Impl = pJavaVirtualMachine_Impl;
2000-09-18 14:29:57 +00:00
}
void OCreatorThread::run() throw() {
_start_Condition.wait();
_start_Condition.reset();
2000-09-18 14:29:57 +00:00
try {
_pJVM = _pJavaVirtualMachine_Impl->createJavaVM(_jvm);
2000-09-18 14:29:57 +00:00
}
catch(RuntimeException & runtimeException) {
_runtimeException = runtimeException;
2000-09-18 14:29:57 +00:00
}
_wait_Condition.set();
2000-09-18 14:29:57 +00:00
2000-12-19 09:20:57 +00:00
if (_pJVM) {
#if defined(WNT) || defined(OS2)
2000-12-19 09:20:57 +00:00
suspend();
2000-09-18 14:29:57 +00:00
#else
_start_Condition.wait();
_start_Condition.reset();
2000-09-18 14:29:57 +00:00
_pJavaVirtualMachine_Impl->disposeJavaVM();
2000-09-18 14:29:57 +00:00
_wait_Condition.set();
#endif
2000-12-19 09:20:57 +00:00
}
}
2000-09-18 14:29:57 +00:00
JavaVM * OCreatorThread::createJavaVM(const JVM & jvm ) throw(RuntimeException) {
_jvm = jvm;
2000-09-18 14:29:57 +00:00
if (!_pJVM) {
2000-12-19 09:20:57 +00:00
create();
_start_Condition.set();
2000-09-18 14:29:57 +00:00
_wait_Condition.wait();
_wait_Condition.reset();
2000-09-18 14:29:57 +00:00
2000-12-19 09:20:57 +00:00
if(!_pJVM)
throw _runtimeException;
}
2000-09-18 14:29:57 +00:00
return _pJVM;
}
2000-09-18 14:29:57 +00:00
void OCreatorThread::disposeJavaVM() throw() {
_start_Condition.set(); // start disposing vm
2000-09-18 14:29:57 +00:00
#ifdef UNX
_wait_Condition.wait(); // wait until disposed
_wait_Condition.reset();
2000-09-18 14:29:57 +00:00
#endif
}
// XServiceInfo
OUString SAL_CALL JavaVirtualMachine_Impl::getImplementationName() throw(RuntimeException)
{
return javavm_getImplementationName();
}
2000-09-18 14:29:57 +00:00
// XServiceInfo
sal_Bool SAL_CALL JavaVirtualMachine_Impl::supportsService(const OUString& ServiceName) throw(RuntimeException) {
Sequence<OUString> aSNL = getSupportedServiceNames();
const OUString * pArray = aSNL.getConstArray();
2000-09-18 14:29:57 +00:00
for (sal_Int32 i = 0; i < aSNL.getLength(); ++ i)
if (pArray[i] == ServiceName)
return sal_True;
2000-09-18 14:29:57 +00:00
return sal_False;
2000-09-18 14:29:57 +00:00
}
// XServiceInfo
Sequence<OUString> SAL_CALL JavaVirtualMachine_Impl::getSupportedServiceNames() throw(RuntimeException)
{
return javavm_getSupportedServiceNames();
2000-09-18 14:29:57 +00:00
}
static void getDefaultLocaleFromConfig(JVM * pjvm,
const Reference<XMultiComponentFactory> & xSMgr,
const Reference<XComponentContext> &xCtx ) throw(Exception)
{
Reference<XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry")),
xCtx );
if(!xConfRegistry.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
Reference<XSimpleRegistry> xConfRegistry_simple(xConfRegistry, UNO_QUERY);
if(!xConfRegistry_simple.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
2001-07-19 06:44:04 +00:00
xConfRegistry_simple->open(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")), sal_True, sal_False);
Reference<XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
2000-09-18 14:29:57 +00:00
2001-07-19 06:44:04 +00:00
// read locale
Reference<XRegistryKey> locale = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("L10N/ooLocale")));
if(locale.is() && locale->getStringValue().getLength()) {
OUString language;
OUString country;
2000-09-18 14:29:57 +00:00
sal_Int32 index = locale->getStringValue().indexOf((sal_Unicode) '-');
2000-09-18 14:29:57 +00:00
if(index >= 0) {
language = locale->getStringValue().copy(0, index);
country = locale->getStringValue().copy(index + 1);
2000-09-18 14:29:57 +00:00
if(language.getLength()) {
OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.language="));
prop += language;
2000-09-18 14:29:57 +00:00
pjvm->pushProp(prop);
}
2000-09-18 14:29:57 +00:00
if(country.getLength()) {
OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.region="));
prop += country;
pjvm->pushProp(prop);
}
}
}
xConfRegistry_simple->close();
}
2000-09-18 14:29:57 +00:00
static void setTimeZone(JVM * pjvm) throw() {
/* A Bug in the Java function
** struct Hjava_util_Properties * java_lang_System_initProperties(
** struct Hjava_lang_System *this,
** struct Hjava_util_Properties *props);
** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
*/
struct tm *tmData;
time_t clock = time(NULL);
tzset();
tmData = localtime(&clock);
#ifdef MACOSX
char * p = tmData->tm_zone;
#else
char * p = tzname[0];
#endif
2000-09-18 14:29:57 +00:00
if (!strcmp(TIMEZONE, p))
pjvm->pushProp(OUString::createFromAscii("user.timezone=ECT"));
2000-09-18 14:29:57 +00:00
}
static void getINetPropsFromConfig(JVM * pjvm,
const Reference<XMultiComponentFactory> & xSMgr,
const Reference<XComponentContext> &xCtx ) throw (Exception)
{
Reference<XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry")),
xCtx );
if(!xConfRegistry.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
Reference<XSimpleRegistry> xConfRegistry_simple(xConfRegistry, UNO_QUERY);
if(!xConfRegistry_simple.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
xConfRegistry_simple->open(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet")), sal_True, sal_False);
Reference<XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
2000-09-18 14:29:57 +00:00
// read ftp proxy name
2001-07-19 06:44:04 +00:00
Reference<XRegistryKey> ftpProxy_name = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyName")));
if(ftpProxy_name.is() && ftpProxy_name->getStringValue().getLength()) {
OUString ftpHost = OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyHost="));
ftpHost += ftpProxy_name->getStringValue();
2000-09-18 14:29:57 +00:00
// read ftp proxy port
2001-07-19 06:44:04 +00:00
Reference<XRegistryKey> ftpProxy_port = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyPort")));
if(ftpProxy_port.is() && ftpProxy_port->getLongValue()) {
OUString ftpPort = OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort="));
ftpPort += OUString::valueOf(ftpProxy_port->getLongValue());
2000-09-18 14:29:57 +00:00
pjvm->pushProp(ftpHost);
pjvm->pushProp(ftpPort);
}
}
2000-09-18 14:29:57 +00:00
// read http proxy name
2001-07-19 06:44:04 +00:00
Reference<XRegistryKey> httpProxy_name = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyName")));
if(httpProxy_name.is() && httpProxy_name->getStringValue().getLength()) {
OUString httpHost = OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyHost="));
httpHost += httpProxy_name->getStringValue();
2000-09-18 14:29:57 +00:00
// read http proxy port
2001-07-19 06:44:04 +00:00
Reference<XRegistryKey> httpProxy_port = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyPort")));
if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
OUString httpPort = OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort="));
httpPort += OUString::valueOf(httpProxy_port->getLongValue());
2000-09-18 14:29:57 +00:00
pjvm->pushProp(httpHost);
pjvm->pushProp(httpPort);
}
}
2000-09-18 14:29:57 +00:00
xConfRegistry_simple->close();
}
2000-09-18 14:29:57 +00:00
static void getJavaPropsFromConfig(JVM * pjvm,
const Reference<XMultiComponentFactory> & xSMgr,
const Reference<XComponentContext> &xCtx) throw(Exception)
{
Reference<XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry")),
xCtx);
if(!xConfRegistry.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
Reference<XSimpleRegistry> xConfRegistry_simple(xConfRegistry, UNO_QUERY);
if(!xConfRegistry_simple.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
2001-07-19 06:44:04 +00:00
xConfRegistry_simple->open(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")), sal_True, sal_False);
Reference<XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
2000-09-18 14:29:57 +00:00
2001-07-19 06:44:04 +00:00
Reference<XRegistryKey> key_InstallPath = xRegistryRootKey->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Office/ooSetupInstallPath")));
if(!key_InstallPath.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: can not find key: Office/InstallPath in org.openoffice.UserProfile")),
Reference<XInterface>());
2000-09-18 14:29:57 +00:00
OUString rcPath = key_InstallPath->getStringValue();
2000-09-18 14:29:57 +00:00
Reference<XInterface> xIniManager(xSMgr->createInstanceWithContext(
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.config.INIManager")),
xCtx));
if(!xIniManager.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get: com.sun.star.config.INIManager")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
Reference<XSimpleRegistry> xIniManager_simple(xIniManager, UNO_QUERY);
if(!xIniManager_simple.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get: com.sun.star.config.INIManager")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
2001-05-21 14:57:33 +00:00
// normalize the path
OUString urlrcPath;
if( osl_File_E_None != File::getFileURLFromSystemPath( rcPath, urlrcPath ) )
{
urlrcPath = rcPath;
}
urlrcPath += OUString(RTL_CONSTASCII_USTRINGPARAM("/config/" INI_FILE));
xIniManager_simple->open(urlrcPath, sal_True, sal_False);
2000-09-18 14:29:57 +00:00
Reference<XRegistryKey> xJavaSection = xIniManager_simple->getRootKey()->openKey(OUString(RTL_CONSTASCII_USTRINGPARAM("Java")));
if(!xJavaSection.is() || !xJavaSection->isValid())
throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: can not find java section in " INI_FILE)), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
Sequence<OUString> javaProperties = xJavaSection->getKeyNames();
OUString * pSectionEntry = javaProperties.getArray();
sal_Int32 nCount = javaProperties.getLength();
2000-09-18 14:29:57 +00:00
2001-10-17 14:52:51 +00:00
for(sal_Int32 i=0; i < nCount; ++ i)
{
//Reconstruct the whole lines of the java.ini
Reference< XRegistryKey > key= xJavaSection->openKey(pSectionEntry[i]);
if (key.is())
{
// there was a "=" in the line, hence key/value pair.
OUString entryValue = key->getStringValue();
2000-09-18 14:29:57 +00:00
2001-10-17 14:52:51 +00:00
if(entryValue.getLength()) {
pSectionEntry[i] += OUString(RTL_CONSTASCII_USTRINGPARAM("="));
pSectionEntry[i] += entryValue;
}
}
2000-09-18 14:29:57 +00:00
pjvm->pushProp(pSectionEntry[i]);
}
2000-09-18 14:29:57 +00:00
xIniManager_simple->close();
2000-09-18 14:29:57 +00:00
}
static void getJavaPropsFromEnvironment(JVM * pjvm) throw() {
// try some defaults for CLASSPATH and runtime lib
const char * pClassPath = getenv("CLASSPATH");
pjvm->setSystemClasspath(OUString::createFromAscii(pClassPath));
2000-09-18 14:29:57 +00:00
pjvm->setRuntimeLib(OUString::createFromAscii(DEF_JAVALIB));
pjvm->setEnabled(1);
2000-09-18 14:29:57 +00:00
// See if properties have been set and parse them
const char * pOOjavaProperties = getenv(PROPERTIES_ENV);
if(pOOjavaProperties) {
OUString properties(OUString::createFromAscii(pOOjavaProperties));
2000-09-18 14:29:57 +00:00
sal_Int32 index;
sal_Int32 lastIndex = 0;
2000-09-18 14:29:57 +00:00
do {
index = properties.indexOf((sal_Unicode)',', lastIndex);
OUString token = (index == -1) ? properties.copy(lastIndex) : properties.copy(lastIndex, index - lastIndex);
2000-09-18 14:29:57 +00:00
lastIndex = index + 1;
2000-09-18 14:29:57 +00:00
pjvm->pushProp(token);
}
while(index > -1);
}
}
2000-09-18 14:29:57 +00:00
static void initVMConfiguration(JVM * pjvm,
const Reference<XMultiComponentFactory> & xSMgr,
const Reference<XComponentContext > &xCtx) throw() {
try {
JVM jvm;
2000-09-18 14:29:57 +00:00
getINetPropsFromConfig(&jvm, xSMgr, xCtx);
*pjvm = jvm;
}
catch(Exception & exception) {
#ifdef DEBUG
OString message = OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
OSL_TRACE("javavm.cxx: can not get INetProps cause of >%s<", message.getStr());
#endif
}
2000-09-18 14:29:57 +00:00
try {
JVM jvm;
getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
}
catch(Exception & exception) {
#ifdef DEBUG
OString message = OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
OSL_TRACE("javavm.cxx: can not get locale cause of >%s<", message.getStr());
#endif
}
try {
JVM jvm;
getJavaPropsFromConfig(&jvm, xSMgr,xCtx);
*pjvm = jvm;
}
catch(Exception & exception) {
#ifdef DEBUG
OString message = OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
OSL_TRACE("javavm.cxx: couldn't use configuration cause of >%s<", message.getStr());
#endif
JVM jvm;
getJavaPropsFromEnvironment(&jvm);
*pjvm = jvm;
2000-09-18 14:29:57 +00:00
}
setTimeZone(pjvm);
2000-09-18 14:29:57 +00:00
2001-05-09 08:35:40 +00:00
// pjvm->setPrint(vm_vfprintf);
// pjvm->setExit(vm_exit);
// pjvm->setAbort(vm_abort);
}
2000-09-18 14:29:57 +00:00
JavaVirtualMachine_Impl::JavaVirtualMachine_Impl(const Reference< XComponentContext > &xCtx) throw()
: _pVMContext(NULL)
, _creatorThread(this)
, _pJava_environment(NULL)
, _xSMgr( xCtx->getServiceManager() )
, _xCtx( xCtx )
2000-09-18 14:29:57 +00:00
{
}
JavaVirtualMachine_Impl::~JavaVirtualMachine_Impl() throw() {
if (_pVMContext)
_creatorThread.disposeJavaVM();
}
2000-09-18 14:29:57 +00:00
JavaVM * JavaVirtualMachine_Impl::createJavaVM(const JVM & jvm) throw(RuntimeException) {
if(!_javaLib.load(jvm.getRuntimeLib())) {
OUString message(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::createJavaVM - cannot find java runtime: "));
message += jvm.getRuntimeLib();
2000-09-18 14:29:57 +00:00
throw RuntimeException(message, Reference<XInterface>());
}
2000-09-18 14:29:57 +00:00
JNI_InitArgs_Type * initArgs = (JNI_InitArgs_Type *)_javaLib.getSymbol(OUString::createFromAscii("JNI_GetDefaultJavaVMInitArgs"));
JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *)_javaLib.getSymbol(OUString::createFromAscii("JNI_CreateJavaVM"));
if (!initArgs || !pCreateJavaVM) {
OUString message(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::createJavaVM - cannot find symbols: JNI_GetDefaultJavaVMInitArgs or JNI_CreateJavaVM "));
2000-09-18 14:29:57 +00:00
throw RuntimeException(message, Reference<XInterface>());
}
2000-09-18 14:29:57 +00:00
JNIEnv * pJNIEnv = NULL;
JavaVM * pJavaVM;
2000-09-18 14:29:57 +00:00
2001-04-25 10:31:24 +00:00
// Try VM 1.1
JDK1_1InitArgs vm_args;
vm_args.version= 0x00010001;
jint ret= initArgs(&vm_args);
jvm.setArgs(&vm_args);
jint err;
err= pCreateJavaVM(&pJavaVM, &pJNIEnv, &vm_args);
if( err != 0)
{
// Try VM 1.2
// The office sets a signal handler at startup. That causes a crash
// with java 1.3 under Solaris. To make it work, we set back the
// handler
#ifdef UNX
struct sigaction act;
act.sa_handler=SIG_DFL;
act.sa_flags= 0;
sigaction( SIGSEGV, &act, NULL);
sigaction( SIGPIPE, &act, NULL);
sigaction( SIGBUS, &act, NULL);
sigaction( SIGILL, &act, NULL);
sigaction( SIGFPE, &act, NULL);
#endif
2001-10-17 14:52:51 +00:00
sal_uInt16 cprops= jvm.getProperties().size();
2001-04-25 10:31:24 +00:00
JavaVMInitArgs vm_args2;
2001-10-17 14:52:51 +00:00
JavaVMOption * options= new JavaVMOption[cprops + 1];
OString sClassPath= OString("-Djava.class.path=") + vm_args.classpath;
options[0].optionString= (char*)sClassPath.getStr();
2001-04-25 10:31:24 +00:00
options[0].extraInfo= NULL;
2001-09-25 05:39:19 +00:00
2001-10-17 14:52:51 +00:00
OString * arProps= new OString[cprops];
2001-09-25 05:39:19 +00:00
2001-10-17 14:52:51 +00:00
OString sPattern("-X");
for( sal_uInt16 x= 0; x< cprops; x++)
2001-09-25 05:39:19 +00:00
{
2001-10-17 14:52:51 +00:00
OString sOption(vm_args.properties[x]);
if ( ! sOption.matchIgnoreAsciiCase(sPattern, 0))
arProps[x]= OString("-D") + vm_args.properties[x];
else
arProps[x]= vm_args.properties[x];
options[x+1].optionString= (char*)arProps[x].getStr();
options[x+1].extraInfo= NULL;
2001-09-25 05:39:19 +00:00
}
2001-04-25 10:31:24 +00:00
vm_args2.version= 0x00010002;
vm_args2.options= options;
2001-10-17 14:52:51 +00:00
vm_args2.nOptions= cprops + 1;
2001-04-25 10:31:24 +00:00
vm_args2.ignoreUnrecognized= JNI_TRUE;
err= pCreateJavaVM(&pJavaVM, &pJNIEnv, &vm_args2);
2001-09-25 05:39:19 +00:00
delete [] options;
2001-10-17 14:52:51 +00:00
delete [] arProps;
2001-04-25 10:31:24 +00:00
}
if(err) {
OUString message(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::createJavaVM - can not create vm, cause of err:"));
message += OUString::valueOf((sal_Int32)err);
throw RuntimeException(message, Reference<XInterface>());
}
2000-09-18 14:29:57 +00:00
return pJavaVM;
2000-09-18 14:29:57 +00:00
}
// XJavaVM
Any JavaVirtualMachine_Impl::getJavaVM(const Sequence<sal_Int8> & processId) throw (RuntimeException) {
MutexGuard guarg(_Mutex);
2000-09-18 14:29:57 +00:00
Sequence<sal_Int8> localProcessID(16);
rtl_getGlobalProcessId( (sal_uInt8*) localProcessID.getArray() );
2000-09-18 14:29:57 +00:00
2000-12-19 09:20:57 +00:00
if (localProcessID == processId && !_pVMContext) {
if(_error.getLength()) // do we have an error?
throw RuntimeException(_error, Reference<XInterface>());
uno_Environment ** ppEnviroments = NULL;
sal_Int32 size = 0;
OUString java(OUString::createFromAscii("java"));
2000-09-18 14:29:57 +00:00
uno_getRegisteredEnvironments(&ppEnviroments, &size, (uno_memAlloc)malloc, java.pData);
2000-09-18 14:29:57 +00:00
if(size) { // do we found an existing java environment?
OSL_TRACE("javavm.cxx: found an existing environment");
2000-09-18 14:29:57 +00:00
_pJava_environment = ppEnviroments[0];
_pJava_environment->acquire(_pJava_environment);
_pVMContext = (JavaVMContext *)_pJava_environment->pContext;
2000-09-18 14:29:57 +00:00
for(sal_Int32 i = 0; i < size; ++ i)
ppEnviroments[i]->release(ppEnviroments[i]);
2000-09-18 14:29:57 +00:00
free(ppEnviroments);
2000-09-18 14:29:57 +00:00
}
else {
JVM jvm;
JavaVM * pJavaVM;
2000-09-18 14:29:57 +00:00
initVMConfiguration(&jvm, _xSMgr, _xCtx);
2000-09-18 14:29:57 +00:00
if (jvm.isEnabled()) {
// create the java vm
2000-12-19 09:20:57 +00:00
try {
pJavaVM = _creatorThread.createJavaVM(jvm);
}
catch(RuntimeException & runtimeException) {
// save the error message
_error = runtimeException.Message;
throw;
}
2000-09-18 14:29:57 +00:00
// create a context
_pVMContext = new JavaVMContext(pJavaVM);
2000-09-18 14:29:57 +00:00
// register the java vm at the uno runtime
uno_getEnvironment(&_pJava_environment, java.pData, _pVMContext);
}
2000-09-18 14:29:57 +00:00
}
}
2000-09-18 14:29:57 +00:00
Any any;
if(_pVMContext) {
if(sizeof(_pVMContext->_pJavaVM) == sizeof(sal_Int32)) { // 32 bit system?
sal_Int32 nP = (sal_Int32)_pVMContext->_pJavaVM;
any <<= nP;
}
else if(sizeof(_pVMContext->_pJavaVM) == sizeof(sal_Int64)) { // 64 bit system?
sal_Int64 nP = (sal_Int64)_pVMContext->_pJavaVM;
any <<= nP;
}
}
2000-09-18 14:29:57 +00:00
return any;
}
2000-09-18 14:29:57 +00:00
// XJavaVM
sal_Bool JavaVirtualMachine_Impl::isVMStarted(void) throw(RuntimeException) {
return _pVMContext != NULL;
}
2000-09-18 14:29:57 +00:00
// XJavaVM
sal_Bool JavaVirtualMachine_Impl::isVMEnabled(void) throw(RuntimeException) {
JVM jvm;
2000-09-18 14:29:57 +00:00
initVMConfiguration(&jvm, _xSMgr, _xCtx);
2000-09-18 14:29:57 +00:00
return jvm.isEnabled();
}
2000-09-18 14:29:57 +00:00
// XJavaThreadRegister_11
sal_Bool JavaVirtualMachine_Impl::isThreadAttached(void) throw (RuntimeException) {
if(!_pVMContext)
throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::isThreadAttached - not vm context")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
return _pVMContext->isThreadAttached();
2000-09-18 14:29:57 +00:00
}
// XJavaThreadRegister_11
void JavaVirtualMachine_Impl::registerThread(void) throw (RuntimeException) {
if(!_pVMContext)
throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::registerThread - not vm context")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
_pVMContext->registerThread();
2000-09-18 14:29:57 +00:00
}
// XJavaThreadRegister_11
void JavaVirtualMachine_Impl::revokeThread(void) throw (RuntimeException) {
if(!_pVMContext)
throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("JavaVirtualMachine_Impl::revokeThread - not vm context")), Reference<XInterface>());
2000-09-18 14:29:57 +00:00
_pVMContext->revokeThread();
}
2000-09-18 14:29:57 +00:00
// JavaVirtualMachine_Impl_CreateInstance()
static Reference<XInterface> SAL_CALL JavaVirtualMachine_Impl_createInstance(const Reference<XComponentContext> & xCtx)
throw (RuntimeException)
{
Reference< XInterface > xRet;
{
MutexGuard guard( Mutex::getGlobalMutex() );
// The javavm is never destroyed !
static Reference< XInterface > *pStaticRef = 0;
if( pStaticRef )
{
xRet = *pStaticRef;
}
else
{
xRet = *new JavaVirtualMachine_Impl( xCtx);
pStaticRef = new Reference< XInterface> ( xRet );
}
}
return xRet;
}
2000-09-18 14:29:57 +00:00
void JavaVirtualMachine_Impl::disposeJavaVM() throw() {
if (_pVMContext){
// pJavaVM->DestroyJavaVM();
// _pJavaVM = NULL;
}
}
}
2000-09-18 14:29:57 +00:00
using namespace stoc_javavm;
2000-09-18 14:29:57 +00:00
static struct ImplementationEntry g_entries[] =
{
{
JavaVirtualMachine_Impl_createInstance, javavm_getImplementationName,
javavm_getSupportedServiceNames, createSingleComponentFactory,
0 , 0
},
{ 0, 0, 0, 0, 0, 0 }
};
extern "C"
{
// NOTE: component_canUnload is not exported, as the library cannot be unloaded.
//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
void * pServiceManager, void * pRegistryKey )
{
return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
2000-09-18 14:29:57 +00:00
}