20#include <rtl/process.h>
23#include <uno/environment.h>
24#include <uno/lbnames.h>
25#include <uno/mapping.hxx>
26#include <com/sun/star/uno/RuntimeException.hpp>
27#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
35#include <com/sun/star/java/XJavaVM.hpp>
38#pragma clang diagnostic push
39#pragma clang diagnostic ignored "-Wunknown-attributes"
43#pragma clang diagnostic pop
46#include <rtl/random.h>
47#include <rtl/ustrbuf.hxx>
48#include <osl/security.hxx>
56#include <com/sun/star/bridge/UnoUrlResolver.hpp>
57#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
58#include <com/sun/star/loader/XImplementationLoader.hpp>
59#include <com/sun/star/lang/XServiceInfo.hpp>
60#include <com/sun/star/lang/XInitialization.hpp>
61#include <com/sun/star/uno/XComponentContext.hpp>
62#include <com/sun/star/util/theMacroExpander.hpp>
76using namespace css::java;
77using namespace css::lang;
78using namespace css::loader;
79using namespace css::uno;
80using namespace css::registry;
82using namespace ::
cppu;
94 if (s_hPool ==
nullptr)
97 if (rtl_random_getBytes(
102 for (
unsigned char byte :
bytes) {
103 buf.append(
static_cast<sal_Int32
>(
byte), 0x10 );
105 return buf.makeStringAndClear();
112std::vector<OUString> getCmdBootstrapVariables()
114 std::vector<OUString> ret;
115 sal_uInt32
count = osl_getCommandArgCount();
116 for (sal_uInt32
i = 0;
i <
count;
i++)
119 osl_getCommandArg(
i, &arg.pData);
120 if (arg.startsWith(
"-env:"))
128 OUString
const & appURL, Sequence<OUString>
const &
args )
131 oslProcess hProcess =
nullptr;
132 oslProcessError rc = osl_executeProcess(
134 reinterpret_cast<rtl_uString **
>(
135 const_cast<OUString *
>(
args.getConstArray()) ),
137 osl_Process_DETACHED,
144 case osl_Process_E_None:
146 case osl_Process_E_NotFound:
148 case osl_Process_E_TimedOut:
150 case osl_Process_E_NoPermission:
152 case osl_Process_E_Unknown:
154 case osl_Process_E_InvalidError:
163Reference<XComponentContext> raise_uno_process(
164 Reference<XComponentContext>
const & xContext)
166 OSL_ASSERT( xContext.is() );
168 OUString
const url(css::util::theMacroExpander::get(xContext)->
expandMacros(
"$URE_BIN_DIR/uno"));
170 const OUString connectStr =
"uno:pipe,name=" +
generateRandomPipeId() +
";urp;uno.ComponentContext";
176 std::vector<OUString>
args{
177#if OSL_DEBUG_LEVEL == 0
184 "-env:INIFILENAME=" };
187 std::vector<OUString> bootvars = getCmdBootstrapVariables();
188 args.insert(
args.end(), bootvars.begin(), bootvars.end());
195 OUStringBuffer sMsg =
"error starting process: " + url;
196 for (
const auto& arg :
args) {
197 sMsg.append(
" " + arg);
199 throw css::uno::RuntimeException(sMsg.makeStringAndClear());
203 Reference<css::bridge::XUnoUrlResolver>
const xUnoUrlResolver(
204 css::bridge::UnoUrlResolver::create(xContext) );
206 for (
int i = 0;
i <= 40; ++
i)
209 return Reference<XComponentContext>(
210 xUnoUrlResolver->resolve(connectStr),
213 catch (
const css::connection::NoConnectException &) {
215 std::this_thread::sleep_for( std::chrono::milliseconds(500) );
224 if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
232class JavaComponentLoader
234 ,
public WeakComponentImplHelper<XImplementationLoader, XServiceInfo>
259 const css::uno::Reference<XImplementationLoader> & getJavaLoader(OUString &);
264 explicit JavaComponentLoader(css::uno::Reference<XComponentContext> xCtx);
272 virtual void SAL_CALL disposing()
override;
275 virtual css::uno::Reference<XInterface> SAL_CALL activate(
276 const OUString& implementationName,
const OUString& implementationLoaderUrl,
277 const OUString& locationUrl,
const css::uno::Reference<XRegistryKey>& xKey)
override;
278 virtual sal_Bool SAL_CALL writeRegistryInfo(
279 const css::uno::Reference<XRegistryKey>& xKey,
280 const OUString& implementationLoaderUrl,
const OUString& locationUrl)
override;
285void JavaComponentLoader::disposing()
299const css::uno::Reference<XImplementationLoader> & JavaComponentLoader::getJavaLoader(OUString & rRemoteArg)
301 static std::mutex ourMutex;
302 std::unique_lock aGuard(ourMutex);
308 if (rRemoteArg.isEmpty()) {
310 Reference<css::container::XHierarchicalNameAccess>
const xConf(
312 "com.sun.star.configuration.ReadOnlyAccess",
313 { Any(OUString(
"*")) },
319 Any const value(xConf->getByHierarchicalName(
320 "org.openoffice.Office.Java/VirtualMachine/RunUnoComponentsOutOfProcess"));
322 if ((value >>= b) && b) {
323 SAL_INFO(
"stoc.java",
"JavaComponentLoader: starting uno process");
329 SAL_INFO(
"stoc.java",
"JavaComponentLoader: creating remote instance to start JVM in uno process");
331 Reference<XImplementationLoader>
const xLoader(
335 assert(xLoader.is());
337 rRemoteArg =
"remote";
338 SAL_INFO(
"stoc.java",
"JavaComponentLoader: remote proxy instance created: " <<
m_javaLoader.get());
345 typelib_InterfaceTypeDescription * pType_XImplementationLoader =
nullptr;
349 css::uno::Reference<XJavaVM> javaVM_xJavaVM(
352 "com.sun.star.java.theJavaVirtualMachine")),
359 Sequence<sal_Int8> processID(17);
360 rtl_getGlobalProcessId(
reinterpret_cast<sal_uInt8 *
>(processID.getArray()));
361 processID.getArray()[16] = 1;
368 static_assert(
sizeof (sal_Int64)
370 sal_Int64 nPointer =
reinterpret_cast< sal_Int64
>(
372 javaVM_xJavaVM->getJavaVM(processID) >>= nPointer;
375 if (!xVirtualMachine.is())
383 SAL_WARN(
"stoc",
"getJavaVM returned null");
390 xVirtualMachine->getVirtualMachine());
391 JNIEnv * pJNIEnv = aGuard2.getEnvironment();
394 jclass jcClassLoader = pJNIEnv->FindClass(
"java/lang/ClassLoader");
395 if(pJNIEnv->ExceptionOccurred())
397 "javaloader error - could not find class java/lang/ClassLoader");
398 jmethodID jmLoadClass = pJNIEnv->GetMethodID(
399 jcClassLoader,
"loadClass",
400 "(Ljava/lang/String;)Ljava/lang/Class;");
401 if(pJNIEnv->ExceptionOccurred())
403 "javaloader error - could not find method java/lang/ClassLoader.loadClass");
405 arg.l = pJNIEnv->NewStringUTF(
406 "com.sun.star.comp.loader.JavaLoader");
407 if(pJNIEnv->ExceptionOccurred())
409 "javaloader error - could not create string");
410 jclass jcJavaLoader =
static_cast< jclass
>(
411 pJNIEnv->CallObjectMethodA(
412 static_cast< jobject
>(xVirtualMachine->getClassLoader()),
414 if(pJNIEnv->ExceptionOccurred())
416 "javaloader error - could not find class com/sun/star/comp/loader/JavaLoader");
417 jmethodID jmJavaLoader_init = pJNIEnv->GetMethodID(jcJavaLoader,
"<init>",
"()V");
418 if(pJNIEnv->ExceptionOccurred())
420 "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed");
421 jobject joJavaLoader = pJNIEnv->NewObject(jcJavaLoader, jmJavaLoader_init);
422 if(pJNIEnv->ExceptionOccurred())
424 "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed");
427 OUString sJava(
"java");
429 xVirtualMachine.get());
430 if(!pJava_environment)
432 "javaloader error - no Java environment available");
435 OUString sCppu_current_lb_name(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
437 if(!pUno_environment)
439 "javaloader error - no C++ environment available");
441 Mapping java_curr(pJava_environment, pUno_environment);
444 "javaloader error - no mapping from java to C++ ");
447 pJava_environment->release(pJava_environment);
448 pJava_environment =
nullptr;
451 pUno_environment->release(pUno_environment);
452 pUno_environment =
nullptr;
456 if(!pType_XImplementationLoader)
458 "javaloader error - no type information for XImplementationLoader");
460 m_javaLoader.set(
static_cast<XImplementationLoader *
>(java_curr.mapInterface(joJavaLoader, pType_XImplementationLoader)));
461 pJNIEnv->DeleteLocalRef( joJavaLoader );
464 "javaloader error - mapping of java XImplementationLoader to c++ failed");
467 pType_XImplementationLoader =
nullptr;
472 throw css::lang::WrappedTargetRuntimeException(
473 "jvmaccess::VirtualMachine::AttachGuard::CreationException",
478 css::uno::Reference<XInitialization> javaLoader_XInitialization(
m_javaLoader, UNO_QUERY_THROW);
483 javaLoader_XInitialization->initialize(Sequence<Any>(&any, 1));
486 if(pJava_environment)
487 pJava_environment->release(pJava_environment);
490 pUno_environment->release(pUno_environment);
492 if(pType_XImplementationLoader)
501JavaComponentLoader::JavaComponentLoader(css::uno::Reference<XComponentContext> xCtx)
509OUString SAL_CALL JavaComponentLoader::getImplementationName()
511 return "com.sun.star.comp.stoc.JavaComponentLoader";
514sal_Bool SAL_CALL JavaComponentLoader::supportsService(
const OUString & ServiceName)
519Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames()
521 return {
"com.sun.star.loader.Java",
"com.sun.star.loader.Java2" };
526sal_Bool SAL_CALL JavaComponentLoader::writeRegistryInfo(
527 const css::uno::Reference<XRegistryKey> & xKey,
const OUString & blabla,
528 const OUString & rLibName)
530 OUString remoteArg(blabla);
531 const css::uno::Reference<XImplementationLoader> &
loader = getJavaLoader(remoteArg);
533 throw CannotRegisterImplementationException(
"Could not create Java implementation loader");
534 return loader->writeRegistryInfo(xKey, remoteArg, rLibName);
537css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader::activate(
538 const OUString & rImplName,
const OUString & blabla,
const OUString & rLibName,
539 const css::uno::Reference<XRegistryKey> & xKey)
541 OUString remoteArg(blabla);
542 if (rImplName.isEmpty() && blabla.isEmpty() && rLibName.isEmpty())
545 (void)getJavaLoader(remoteArg);
546 return css::uno::Reference<XInterface>();
549 const css::uno::Reference<XImplementationLoader> &
loader = getJavaLoader(remoteArg);
551 throw CannotActivateFactoryException(
"Could not create Java implementation loader");
552 return loader->activate(rImplName, remoteArg, rLibName, xKey);
555extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
557 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const&)
560 return cppu::acquire(
new JavaComponentLoader(context));
565 "could not init javaloader due to " << runtimeException);
css::uno::Type const & get()
struct _uno_Environment uno_Environment
css::uno::Reference< XComponentContext > m_xComponentContext
local context
css::uno::Reference< XImplementationLoader > m_javaLoader
Do not use m_javaLoader directly.
css::uno::Reference< XComponentContext > m_xRemoteComponentContext
possible remote process' context (use depends on configuration).
void SAL_CALL uno_getEnvironment(uno_Environment **ppEnv, rtl_uString *pEnvDcp, void *pContext) SAL_THROW_EXTERN_C()
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
struct _typelib_TypeDescription typelib_TypeDescription
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
OUString expandMacros(OUString const &text)
OUString generateRandomPipeId()
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC oslProcess raiseProcess(OUString const &appURL, css::uno::Sequence< OUString > const &args)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stoc_JavaComponentLoader_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
std::vector< sal_uInt8 > bytes
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()