// from desktop/source/deployment/misc/dp_misc.cxx
OUString generateRandomPipeId()
{ // compute some good pipe id:
sal_uInt8 bytes[ 32 ]; if (rtl_random_getBytes(
nullptr, bytes, SAL_N_ELEMENTS(bytes) ) != rtl_Random_E_None) { throw RuntimeException( u"random pool error!?"_ustr, nullptr );
}
OUStringBuffer buf; for (unsignedchar byte : bytes) {
buf.append( static_cast<sal_Int32>(byte), 0x10 );
} return buf.makeStringAndClear();
}
// from desktop/source/deployment/registry/component/dp_component.cxx /** return a vector of bootstrap variables which have been provided ascommandarguments.
*/
std::vector<OUString> getCmdBootstrapVariables()
{
std::vector<OUString> ret;
sal_uInt32 count = osl_getCommandArgCount(); for (sal_uInt32 i = 0; i < count; i++)
{
OUString arg;
osl_getCommandArg(i, &arg.pData); if (arg.startsWith("-env:"))
ret.push_back(arg);
} return ret;
}
// from desktop/source/deployment/misc/dp_misc.cxx
oslProcess raiseProcess(
OUString const & appURL, Sequence<OUString> const & args )
{
::osl::Security sec;
oslProcess hProcess = nullptr;
oslProcessError rc = osl_executeProcess(
appURL.pData, reinterpret_cast<rtl_uString **>( const_cast<OUString *>(args.getConstArray()) ),
args.getLength(),
osl_Process_DETACHED,
sec.getHandle(),
nullptr, // => current working dir
nullptr, 0, // => no env vars
&hProcess );
switch (rc) { case osl_Process_E_None: break; case osl_Process_E_NotFound: throw RuntimeException( u"image not found!"_ustr, nullptr ); case osl_Process_E_TimedOut: throw RuntimeException( u"timeout occurred!"_ustr, nullptr ); case osl_Process_E_NoPermission: throw RuntimeException( u"permission denied!"_ustr, nullptr ); case osl_Process_E_Unknown: throw RuntimeException( u"unknown error!"_ustr, nullptr ); case osl_Process_E_InvalidError: default: throw RuntimeException( u"unmapped error!"_ustr, nullptr );
}
//now add the bootstrap variables which were supplied on the command line
std::vector<OUString> bootvars = getCmdBootstrapVariables();
args.insert(args.end(), bootvars.begin(), bootvars.end());
for (int i = 0; i <= 40; ++i) // 20 seconds
{ try { return Reference<XComponentContext>(
xUnoUrlResolver->resolve(connectStr),
UNO_QUERY_THROW );
} catch (const css::connection::NoConnectException &) { if (i < 40) {
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
} elsethrow;
}
} return nullptr; // warning C4715
} catch (...) { // try to terminate process: if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
{
OSL_ASSERT( false );
} throw;
}
}
class JavaComponentLoader
: protected ::cppu::BaseMutex
, public WeakComponentImplHelper<XImplementationLoader, XServiceInfo>
{ /** local context */
css::uno::Reference<XComponentContext> m_xComponentContext;
/** possible remote process' context (use depends on configuration). note:lifetimemustbeeffectively"static"asthisJavaComponentLoader hasnocontroloverthelifetimeoftheservicescreatedviathis context;henceJavaComponentLoaderisasingle-instanceservice.
*/
css::uno::Reference<XComponentContext> m_xRemoteComponentContext;
/** Do not use m_javaLoader directly. Instead use getJavaLoader. Thisiseitheranin-processloaderimplementedinJava, oraremoteinstanceofJavaComponentLoaderrunninginunoprocess, actingasaproxy.
*/
css::uno::Reference<XImplementationLoader> m_javaLoader; /** The returned Reference contains a null pointer if the office is not configured torunjava.
void JavaComponentLoader::disposing()
{ // Explicitly drop all remote refs to shut down the uno.bin process // and particularly the connection to it, so that it can't do more calls // during late shutdown.
m_javaLoader.clear(); if (m_xRemoteComponentContext.is()) {
Reference<XComponent> const xComp(m_xRemoteComponentContext, UNO_QUERY);
assert(xComp.is());
xComp->dispose();
m_xRemoteComponentContext.clear();
}
}
// check if the JVM should be instantiated out-of-process if (rRemoteArg.isEmpty()) { if (!m_xRemoteComponentContext.is()) {
Reference<css::container::XHierarchicalNameAccess> const xConf(
m_xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
u"com.sun.star.configuration.ReadOnlyAccess"_ustr,
{ Any(u"*"_ustr) }, // locale isn't relevant here
m_xComponentContext),
UNO_QUERY);
// configmgr is not part of URE, so may not exist! if (xConf.is()) {
Any const value(xConf->getByHierarchicalName(
u"org.openoffice.Office.Java/VirtualMachine/RunUnoComponentsOutOfProcess"_ustr)); bool b; if ((value >>= b) && b) {
SAL_INFO("stoc.java", "JavaComponentLoader: starting uno process");
m_xRemoteComponentContext = raise_uno_process(m_xComponentContext);
}
}
} if (m_xRemoteComponentContext.is()) {
SAL_INFO("stoc.java", "JavaComponentLoader: creating remote instance to start JVM in uno process"); // create JVM service in remote uno.bin process
Reference<XImplementationLoader> const xLoader(
m_xRemoteComponentContext->getServiceManager()->createInstanceWithContext(
u"com.sun.star.loader.Java2"_ustr, m_xRemoteComponentContext),
UNO_QUERY_THROW);
assert(xLoader.is());
m_javaLoader = xLoader;
rRemoteArg = "remote";
SAL_INFO("stoc.java", "JavaComponentLoader: remote proxy instance created: " << m_javaLoader.get()); return m_javaLoader;
}
}
try { // get a java vm, where we can create a loader
css::uno::Reference<XJavaVM> javaVM_xJavaVM(
m_xComponentContext->getValueByName(
(u"/singletons/" "com.sun.star.java.theJavaVirtualMachine"_ustr)),
UNO_QUERY_THROW);
// Use the special protocol of XJavaVM.getJavaVM: If the passed in // process ID has an extra 17th byte of value one, the returned any // contains a pointer to a jvmaccess::UnoVirtualMachine, instead of the // underlying JavaVM pointer:
Sequence<sal_Int8> processID(17);
rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8 *>(processID.getArray()));
processID.getArray()[16] = 1;
// We get a non-refcounted pointer to a jvmaccess::UnoVirtualMachine // from the XJavaVM service (the pointer is guaranteed to be valid // as long as our reference to the XJavaVM service lasts), and // convert the non-refcounted pointer into a refcounted one // immediately:
static_assert(sizeof (sal_Int64)
>= sizeof (jvmaccess::UnoVirtualMachine *), "must be at least the same size");
sal_Int64 nPointer = reinterpret_cast< sal_Int64 >( static_cast< jvmaccess::UnoVirtualMachine * >(nullptr));
javaVM_xJavaVM->getJavaVM(processID) >>= nPointer;
rtl::Reference< jvmaccess::UnoVirtualMachine > xVirtualMachine( reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer)); if (!xVirtualMachine.is())
{ //throw RuntimeException( // "javaloader error - JavaVirtualMachine service could not provide a VM", // css::uno::Reference<XInterface>()); // We must not throw a RuntimeException, because this might end the applications. // It is ok if java components // are not working because the office can be installed without Java support.
SAL_WARN("stoc", "getJavaVM returned null"); return m_javaLoader; // null-ref
}
// instantiate the java JavaLoader
jclass jcClassLoader = pJNIEnv->FindClass("java/lang/ClassLoader"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - could not find class java/lang/ClassLoader"_ustr);
jmethodID jmLoadClass = pJNIEnv->GetMethodID(
jcClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - could not find method java/lang/ClassLoader.loadClass"_ustr);
jvalue arg;
arg.l = pJNIEnv->NewStringUTF( "com.sun.star.comp.loader.JavaLoader"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - could not create string"_ustr);
jclass jcJavaLoader = static_cast< jclass >(
pJNIEnv->CallObjectMethodA( static_cast< jobject >(xVirtualMachine->getClassLoader()),
jmLoadClass, &arg)); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - could not find class com/sun/star/comp/loader/JavaLoader"_ustr);
jmethodID jmJavaLoader_init = pJNIEnv->GetMethodID(jcJavaLoader, "<init>", "()V"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed"_ustr);
jobject joJavaLoader = pJNIEnv->NewObject(jcJavaLoader, jmJavaLoader_init); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(
u"javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed"_ustr);
// map the java JavaLoader to this environment
OUString sJava(u"java"_ustr);
uno_getEnvironment(&pJava_environment, sJava.pData,
xVirtualMachine.get()); if(!pJava_environment) throw RuntimeException(
u"javaloader error - no Java environment available"_ustr);
// why is there no convenient constructor?
OUString sCppu_current_lb_name(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
uno_getEnvironment(&pUno_environment, sCppu_current_lb_name.pData, nullptr); if(!pUno_environment) throw RuntimeException(
u"javaloader error - no C++ environment available"_ustr);
Mapping java_curr(pJava_environment, pUno_environment); if(!java_curr.is()) throw RuntimeException(
u"javaloader error - no mapping from java to C++ "_ustr);
// release uno environment
pUno_environment->release(pUno_environment);
pUno_environment = nullptr;
cppu::UnoType<XImplementationLoader>::get().
getDescription(reinterpret_cast<typelib_TypeDescription **>(&pType_XImplementationLoader)); if(!pType_XImplementationLoader) throw RuntimeException(
u"javaloader error - no type information for XImplementationLoader"_ustr);
m_javaLoader.set(static_cast<XImplementationLoader *>(java_curr.mapInterface(joJavaLoader, pType_XImplementationLoader)));
pJNIEnv->DeleteLocalRef( joJavaLoader ); if(!m_javaLoader.is()) throw RuntimeException(
u"javaloader error - mapping of java XImplementationLoader to c++ failed"_ustr);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.