Use std::unique_ptr<JavaInfo> for lifecycle management in jvmfwk/framework.hxx

Change-Id: Ie604c75e92c407ff3118aaa58155648d956c91fb
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
index bef9f25..51f8b37 100644
--- a/cui/source/options/optjava.cxx
+++ b/cui/source/options/optjava.cxx
@@ -139,10 +139,8 @@ SvxJavaOptionsPage::SvxJavaOptionsPage( vcl::Window* pParent, const SfxItemSet& 
    , m_pParamDlg(nullptr)
    , m_pPathDlg(nullptr)
#if HAVE_FEATURE_JAVA
    , m_parJavaInfo(nullptr)
    , m_parParameters(nullptr)
    , m_pClassPath(nullptr)
    , m_nInfoSize(0)
    , m_nParamSize(0)
#endif
    , m_aResetIdle("cui options SvxJavaOptionsPage Reset")
@@ -221,12 +219,6 @@ void SvxJavaOptionsPage::dispose()
    m_pPathDlg.disposeAndClear();
    ClearJavaInfo();
#if HAVE_FEATURE_JAVA
    std::vector< JavaInfo* >::iterator pIter;
    for ( pIter = m_aAddedInfos.begin(); pIter != m_aAddedInfos.end(); ++pIter )
    {
        JavaInfo* pInfo = *pIter;
        delete pInfo;
    }
    m_aAddedInfos.clear();

    jfw_unlock();
@@ -447,19 +439,7 @@ IMPL_LINK_NOARG( SvxJavaOptionsPage, ExpertConfigHdl_Impl, Button*, void )
void SvxJavaOptionsPage::ClearJavaInfo()
{
#if HAVE_FEATURE_JAVA
    if ( m_parJavaInfo )
    {
        JavaInfo** parInfo = m_parJavaInfo;
        for ( sal_Int32 i = 0; i < m_nInfoSize; ++i )
        {
            JavaInfo* pInfo = *parInfo++;
            delete pInfo;
        }

        rtl_freeMemory( m_parJavaInfo );
        m_parJavaInfo = nullptr;
        m_nInfoSize = 0;
    }
    m_parJavaInfo.clear();
#else
    (void) this;
#endif
@@ -483,50 +463,44 @@ void SvxJavaOptionsPage::LoadJREs()
{
#if HAVE_FEATURE_JAVA
    WaitObject aWaitObj(m_pJavaList);
    javaFrameworkError eErr = jfw_findAllJREs( &m_parJavaInfo, &m_nInfoSize );
    if ( JFW_E_NONE == eErr && m_parJavaInfo )
    javaFrameworkError eErr = jfw_findAllJREs( &m_parJavaInfo );
    if ( JFW_E_NONE == eErr )
    {
        JavaInfo** parInfo = m_parJavaInfo;
        for ( sal_Int32 i = 0; i < m_nInfoSize; ++i )
        for (auto const & pInfo: m_parJavaInfo)
        {
            JavaInfo* pInfo = *parInfo++;
            AddJRE( pInfo );
            AddJRE( pInfo.get() );
        }
    }

    std::vector< JavaInfo* >::iterator pIter;
    for ( pIter = m_aAddedInfos.begin(); pIter != m_aAddedInfos.end(); ++pIter )
    for (auto const & pInfo: m_aAddedInfos)
    {
        JavaInfo* pInfo = *pIter;
        AddJRE( pInfo );
        AddJRE( pInfo.get() );
    }

    JavaInfo* pSelectedJava = nullptr;
    std::unique_ptr<JavaInfo> pSelectedJava;
    eErr = jfw_getSelectedJRE( &pSelectedJava );
    if ( JFW_E_NONE == eErr && pSelectedJava )
    {
        JavaInfo** parInfo = m_parJavaInfo;
        for ( sal_Int32 i = 0; i < m_nInfoSize; ++i )
        sal_Int32 i = 0;
        for (auto const & pCmpInfo: m_parJavaInfo)
        {
            JavaInfo* pCmpInfo = *parInfo++;
            if ( jfw_areEqualJavaInfo( pCmpInfo, pSelectedJava ) )
            if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pSelectedJava.get() ) )
            {
                SvTreeListEntry* pEntry = m_pJavaList->GetEntry(i);
                if ( pEntry )
                    m_pJavaList->HandleEntryChecked( pEntry );
                break;
            }
            ++i;
        }
    }

    delete pSelectedJava;
#else
    (void) this;
#endif
}


void SvxJavaOptionsPage::AddJRE( JavaInfo* _pInfo )
void SvxJavaOptionsPage::AddJRE( JavaInfo const * _pInfo )
{
#if HAVE_FEATURE_JAVA
    OUStringBuffer sEntry;
@@ -573,17 +547,15 @@ void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )
{
#if HAVE_FEATURE_JAVA
    bool bStartAgain = true;
    JavaInfo* pInfo = nullptr;
    std::unique_ptr<JavaInfo> pInfo;
    javaFrameworkError eErr = jfw_getJavaInfoByPath( _rFolder.pData, &pInfo );
    if ( JFW_E_NONE == eErr && pInfo )
    {
        sal_Int32 nPos = 0;
        bool bFound = false;
        JavaInfo** parInfo = m_parJavaInfo;
        for ( sal_Int32 i = 0; i < m_nInfoSize; ++i )
        for (auto const & pCmpInfo: m_parJavaInfo)
        {
            JavaInfo* pCmpInfo = *parInfo++;
            if ( jfw_areEqualJavaInfo( pCmpInfo, pInfo ) )
            if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
            {
                bFound = true;
                break;
@@ -593,11 +565,9 @@ void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )

        if ( !bFound )
        {
            std::vector< JavaInfo* >::iterator pIter;
            for ( pIter = m_aAddedInfos.begin(); pIter != m_aAddedInfos.end(); ++pIter )
            for (auto const & pCmpInfo: m_aAddedInfos)
            {
                JavaInfo* pCmpInfo = *pIter;
                if ( jfw_areEqualJavaInfo( pCmpInfo, pInfo ) )
                if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
                {
                    bFound = true;
                    break;
@@ -609,12 +579,10 @@ void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )
        if ( !bFound )
        {
            jfw_addJRELocation( pInfo->sLocation.pData );
            AddJRE( pInfo );
            m_aAddedInfos.push_back( pInfo );
            AddJRE( pInfo.get() );
            m_aAddedInfos.push_back( std::move(pInfo) );
            nPos = m_pJavaList->GetEntryCount() - 1;
        }
        else
            delete pInfo;

        SvTreeListEntry* pEntry = m_pJavaList->GetEntry( nPos );
        m_pJavaList->Select( pEntry );
@@ -703,17 +671,17 @@ bool SvxJavaOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
    {
        if ( m_pJavaList->GetCheckButtonState( m_pJavaList->GetEntry(i) ) == SvButtonState::Checked )
        {
            JavaInfo* pInfo = nullptr;
            if ( i < static_cast< sal_uLong >( m_nInfoSize ) )
                pInfo = m_parJavaInfo[i];
            JavaInfo const * pInfo;
            if ( i < m_parJavaInfo.size() )
                pInfo = m_parJavaInfo[i].get();
            else
                pInfo = m_aAddedInfos[ i - m_nInfoSize ];
                pInfo = m_aAddedInfos[ i - m_parJavaInfo.size() ].get();

            JavaInfo* pSelectedJava = nullptr;
            std::unique_ptr<JavaInfo> pSelectedJava;
            eErr = jfw_getSelectedJRE( &pSelectedJava );
            if ( JFW_E_NONE == eErr || JFW_E_INVALID_SETTINGS == eErr )
            {
                if (pSelectedJava == nullptr || !jfw_areEqualJavaInfo( pInfo, pSelectedJava ) )
                if (!pSelectedJava || !jfw_areEqualJavaInfo( pInfo, pSelectedJava.get() ) )
                {
                    sal_Bool bRunning = false;
                    eErr = jfw_isVMRunning( &bRunning );
@@ -732,7 +700,6 @@ bool SvxJavaOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
                    bModified = true;
                }
            }
            delete pSelectedJava;
            break;
        }
    }
diff --git a/cui/source/options/optjava.hxx b/cui/source/options/optjava.hxx
index 22a24e8..6b301d2 100644
--- a/cui/source/options/optjava.hxx
+++ b/cui/source/options/optjava.hxx
@@ -21,6 +21,7 @@

#include <config_features.h>

#include <memory>
#include <vector>
#include <ucbhelper/content.hxx>
#include <vcl/button.hxx>
@@ -64,10 +65,9 @@ private:
    VclPtr<SvxJavaClassPathDlg>        m_pPathDlg;

#if HAVE_FEATURE_JAVA
    JavaInfo**              m_parJavaInfo;
    std::vector<std::unique_ptr<JavaInfo>> m_parJavaInfo;
    rtl_uString**           m_parParameters;
    rtl_uString*            m_pClassPath;
    sal_Int32               m_nInfoSize;
    sal_Int32               m_nParamSize;
#endif
    OUString                m_sInstallText;
@@ -78,7 +78,7 @@ private:
    VclPtr<CheckBox>               m_pExperimentalCB;
    VclPtr<CheckBox>               m_pMacroCB;

    std::vector< JavaInfo* >
    std::vector<std::unique_ptr<JavaInfo>>
                            m_aAddedInfos;

    rtl::Reference< ::svt::DialogClosedListener >           xDialogListener;
@@ -100,7 +100,7 @@ private:
    void                    ClearJavaInfo();
    void                    ClearJavaList();
    void                    LoadJREs();
    void                    AddJRE( JavaInfo* _pInfo );
    void                    AddJRE( JavaInfo const * _pInfo );
    void                    HandleCheckEntry( SvTreeListEntry* _pEntry );
    void                    AddFolder( const OUString& _rFolder );

diff --git a/desktop/source/migration/services/jvmfwk.cxx b/desktop/source/migration/services/jvmfwk.cxx
index 042609a..9fb42e9 100644
--- a/desktop/source/migration/services/jvmfwk.cxx
+++ b/desktop/source/migration/services/jvmfwk.cxx
@@ -37,6 +37,7 @@
#include <com/sun/star/configuration/backend/TemplateIdentifier.hpp>
#include <jvmfwk/framework.hxx>
#include "jvmfwk.hxx"
#include <memory>
#include <stack>
#include <stdio.h>

@@ -237,12 +238,12 @@ void JavaMigration::migrateJavarc()
    if (bSuccess && !sValue.isEmpty())
    {
        //get the directory
        jfw::JavaInfoGuard aInfo;
        javaFrameworkError err = jfw_getJavaInfoByPath(sValue.pData, &aInfo.info);
        std::unique_ptr<JavaInfo> aInfo;
        javaFrameworkError err = jfw_getJavaInfoByPath(sValue.pData, &aInfo);

        if (err == JFW_E_NONE)
        {
            if (jfw_setSelectedJRE(aInfo.info) != JFW_E_NONE)
            if (jfw_setSelectedJRE(aInfo.get()) != JFW_E_NONE)
            {
                OSL_FAIL("[Service implementation " IMPL_NAME
                           "] XJob::execute: jfw_setSelectedJRE failed.");
diff --git a/include/jvmfwk/framework.hxx b/include/jvmfwk/framework.hxx
index 8f3a3a0..99d25da 100644
--- a/include/jvmfwk/framework.hxx
+++ b/include/jvmfwk/framework.hxx
@@ -22,6 +22,11 @@
#ifndef INCLUDED_JVMFWK_FRAMEWORK_HXX
#define INCLUDED_JVMFWK_FRAMEWORK_HXX

#include <sal/config.h>

#include <memory>
#include <vector>

#include <jvmfwk/jvmfwkdllapi.hxx>
#include <rtl/byteseq.hxx>
#include <rtl/ustring.h>
@@ -255,26 +260,6 @@ struct JavaInfo
    rtl::ByteSequence arVendorData;
};

namespace jfw {

struct JavaInfoGuard {
    JavaInfoGuard(JavaInfoGuard &) = delete;
    void operator =(JavaInfoGuard) = delete;

    JavaInfoGuard(): info(nullptr) {}

    ~JavaInfoGuard() { delete info; }

    void clear() {
        delete info;
        info = nullptr;
    }

    JavaInfo * info;
};

}

/** compares two <code>JavaInfo</code> objects for equality.

   <p>Two <code>JavaInfo</code> objects are said to be equal if the contained
@@ -371,13 +356,11 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_isVMRunning(sal_Bool *bRunning);
    the first <code>JavaInfo</code> object that is detected by the algorithm
    as described above is used.</p>

    @param ppInfo
    @param pInfo
    [out] a <code>JavaInfo</code> pointer, representing the selected JRE.
    The caller has to delete it. The
    <code>JavaInfo</code> is for informational purposes only. It is not
    The <code>JavaInfo</code> is for informational purposes only. It is not
    necessary to call <code>jfw_setSelectedJRE</code> afterwards.<br/>
    <code>ppInfo</code>can be NULL. If <code>*ppInfo</code> is not null, then it is
    overwritten, without attempting to free <code>*ppInfo</code>.
    <code>pInfo</code>can be NULL.

    @return
    JFW_E_NONE function ran successfully.<br/>
@@ -387,7 +370,7 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_isVMRunning(sal_Bool *bRunning);
    JFW_E_CONFIGURATION mode was not properly set or their prerequisites
    were not met.
 */
JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAndSelectJRE(JavaInfo **pInfo);
JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAndSelectJRE(std::unique_ptr<JavaInfo> *pInfo);

/** provides information about all available JRE installations.

@@ -401,22 +384,18 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAndSelectJRE(JavaInfo **pInfo);
    already an equal object.</p>

    @param parInfo
    [out] on returns it contains a pointer to an array of <code>JavaInfo</code>
    pointers.
    The caller must free the array with <code>rtl_freeMemory</code> and each
    element of the array must be deleted.
    @param pSize
    [out] on return contains the size of array returned in <code>parInfo</code>.
    [out] on returns it contains a vector of <code>JavaInfo</code> pointers.
    Any previously contained elements are removed first.

    @return
    JFW_E_NONE function ran successfully.<br/>
    JFW_E_INVALID_ARG at least on of the parameters was NULL<br/>
    JFW_E_INVALID_ARG parInfo was NULL<br/>
    JFW_E_ERROR an error occurred. <br/>
    JFW_E_CONFIGURATION mode was not properly set or their prerequisites
    were not met.
*/
JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAllJREs(
    JavaInfo ***parInfo, sal_Int32 *pSize);
    std::vector<std::unique_ptr<JavaInfo>> *parInfo);

/** determines if a path points to a Java installation.

@@ -433,7 +412,7 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAllJREs(

   @param pPath
   [in] a file URL to a directory.
   @param pInfo
   @param ppInfo
   [out] the <code>JavaInfo</code> object which represents a JRE found at the
   location specified by <code>pPath</code>

@@ -448,7 +427,7 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_findAllJREs(
   requirements as determined by the javavendors.xml
 */
JVMFWK_DLLPUBLIC javaFrameworkError jfw_getJavaInfoByPath(
    rtl_uString *pPath, JavaInfo **ppInfo);
    rtl_uString *pPath, std::unique_ptr<JavaInfo> *ppInfo);


/** starts a Java Virtual Machine (JVM).
@@ -564,8 +543,7 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_setSelectedJRE(JavaInfo const *pInfo);
    @param ppInfo
    [out] on return it contains a pointer to a <code>JavaInfo</code> object
    that represents the currently selected JRE. When <code>*ppInfo</code> is not
    NULL then the function overwrites the pointer. It is not attempted to free
    the pointer.
    NULL then the function sets the pointer.

    @return
    JFW_E_NONE function ran successfully.<br/>
@@ -575,7 +553,7 @@ JVMFWK_DLLPUBLIC javaFrameworkError jfw_setSelectedJRE(JavaInfo const *pInfo);
    JFW_E_INVALID_SETTINGS the javavendors.xml has been changed and no
    JRE has been selected afterwards. <br/>
 */
JVMFWK_DLLPUBLIC javaFrameworkError jfw_getSelectedJRE(JavaInfo **ppInfo);
JVMFWK_DLLPUBLIC javaFrameworkError jfw_getSelectedJRE(std::unique_ptr<JavaInfo> *ppInfo);


/** determines if Java can be used.
diff --git a/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx b/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx
index 718902c..3c1b190 100644
--- a/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx
+++ b/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx
@@ -17,6 +17,9 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sal/config.h>

#include <memory>

#include <stdio.h>
#include <stdlib.h>
@@ -31,7 +34,7 @@

static bool hasOption(char const * szOption, int argc, char** argv);
static OString getLD_LIBRARY_PATH(const rtl::ByteSequence & vendorData);
static bool findAndSelect(JavaInfo**);
static bool findAndSelect(std::unique_ptr<JavaInfo>*);

#define HELP_TEXT    \
"\njavaldx is necessary to make Java work on some UNIX platforms." \
@@ -64,8 +67,8 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
            return -1;
        }

        jfw::JavaInfoGuard aInfo;
        errcode = jfw_getSelectedJRE(&aInfo.info);
        std::unique_ptr<JavaInfo> aInfo;
        errcode = jfw_getSelectedJRE(&aInfo);

        if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
        {
@@ -73,19 +76,19 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
            return -1;
        }

        if (aInfo.info == nullptr)
        if (!aInfo)
        {
            if (!findAndSelect(&aInfo.info))
            if (!findAndSelect(&aInfo))
                return -1;
        }
        else
        {
            //check if the JRE was not uninstalled
            sal_Bool bExist = false;
            errcode = jfw_existJRE(aInfo.info, &bExist);
            errcode = jfw_existJRE(aInfo.get(), &bExist);
            if (errcode == JFW_E_NONE)
            {
                if (!bExist && !findAndSelect(&aInfo.info))
                if (!bExist && !findAndSelect(&aInfo))
                    return -1;
            }
            else
@@ -95,7 +98,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
            }
        }

        OString sPaths = getLD_LIBRARY_PATH(aInfo.info->arVendorData);
        OString sPaths = getLD_LIBRARY_PATH(aInfo->arVendorData);
        fprintf(stdout, "%s\n", sPaths.getStr());
    }
    catch (const std::exception&)
@@ -135,7 +138,7 @@ static bool hasOption(char const * szOption, int argc, char** argv)
    return retVal;
}

static bool findAndSelect(JavaInfo ** ppInfo)
static bool findAndSelect(std::unique_ptr<JavaInfo> * ppInfo)
{
    javaFrameworkError errcode = jfw_findAndSelectJRE(ppInfo);
    if (errcode == JFW_E_NO_JAVA_FOUND)
diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx
index 22d0665..218e2ec 100644
--- a/jvmfwk/source/framework.cxx
+++ b/jvmfwk/source/framework.cxx
@@ -47,13 +47,14 @@ bool areEqualJavaInfo(

}

javaFrameworkError jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize)
javaFrameworkError jfw_findAllJREs(std::vector<std::unique_ptr<JavaInfo>> *pparInfo)
{
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
        if (pparInfo == nullptr || pSize == nullptr)
        if (pparInfo == nullptr)
            return JFW_E_INVALID_ARG;
        pparInfo->clear();

        jfw::VendorSettings aVendorSettings;
        std::vector<OUString> vecVendors =
@@ -167,23 +168,15 @@ javaFrameworkError jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize)
            if (it_duplicate != vecInfoManual2.end())
                vecInfoManual2.erase(it_duplicate);
        }
        //create an fill the array of JavaInfo*
        sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size();
        *pparInfo = static_cast<JavaInfo**>(rtl_allocateMemory(
            nSize * sizeof(JavaInfo*)));
        if (*pparInfo == nullptr)
            return JFW_E_ERROR;

        typedef std::vector<jfw::CJavaInfo>::iterator it;
        int index = 0;
        //Add the automatically detected JREs
        for (it k = vecInfo.begin(); k != vecInfo.end(); ++k)
            (*pparInfo)[index++] = k->detach();
            pparInfo->push_back(std::unique_ptr<JavaInfo>(k->detach()));
        //Add the manually detected JREs
        for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); ++l)
            (*pparInfo)[index++] = l->detach();
            pparInfo->push_back(std::unique_ptr<JavaInfo>(l->detach()));

        *pSize = nSize;
        return JFW_E_NONE;
    }
    catch (const jfw::FrameworkException& e)
@@ -216,7 +209,7 @@ javaFrameworkError jfw_startVM(

        std::vector<OString> vmParams;
        OString sUserClassPath;
        jfw::CJavaInfo aInfo;
        std::unique_ptr<JavaInfo> aInfo;
        if (pInfo == nullptr)
        {
            jfw::JFW_MODE mode = jfw::getMode();
@@ -225,9 +218,9 @@ javaFrameworkError jfw_startVM(
                const jfw::MergedSettings settings;
                if (!settings.getEnabled())
                    return JFW_E_JAVA_DISABLED;
                aInfo.attach(settings.createJavaInfo());
                aInfo.reset(settings.createJavaInfo());
                //check if a Java has ever been selected
                if (aInfo == nullptr)
                if (!aInfo)
                    return JFW_E_NO_SELECT;

#ifdef _WIN32
@@ -241,7 +234,7 @@ javaFrameworkError jfw_startVM(
                {
                    // If no JRE has been selected then we do not select one. This function shall then
                    //return JFW_E_NO_SELECT
                    if (aInfo != nullptr &&
                    if (aInfo &&
                        (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
                    {
                        //has the user manually selected a JRE?
@@ -281,7 +274,7 @@ javaFrameworkError jfw_startVM(
            } // end mode FWK_MODE_OFFICE
            else if (mode == jfw::JFW_MODE_DIRECT)
            {
                errcode = jfw_getSelectedJRE(&aInfo.pInfo);
                errcode = jfw_getSelectedJRE(&aInfo);
                if (errcode != JFW_E_NONE)
                    return errcode;
                //In direct mode the options are specified by bootstrap variables
@@ -292,7 +285,7 @@ javaFrameworkError jfw_startVM(
            }
            else
                OSL_ASSERT(false);
            pInfo = aInfo.pInfo;
            pInfo = aInfo.get();
        }
        assert(pInfo != nullptr);

@@ -369,7 +362,7 @@ javaFrameworkError jfw_startVM(
    PATH environment variables. If no suitable JavaInfo is found there, it
    inspects all JavaInfos found by the jfw_plugin_get* functions.
 */
javaFrameworkError jfw_findAndSelectJRE(JavaInfo **pInfo)
javaFrameworkError jfw_findAndSelectJRE(std::unique_ptr<JavaInfo> *pInfo)
{
    javaFrameworkError errcode = JFW_E_NONE;
    try
@@ -603,7 +596,7 @@ javaFrameworkError jfw_findAndSelectJRE(JavaInfo **pInfo)
            if (pInfo !=nullptr)
            {
                //copy to out param
                *pInfo = jfw::CJavaInfo::copyJavaInfo(aCurrentInfo.pInfo);
                pInfo->reset(jfw::CJavaInfo::copyJavaInfo(aCurrentInfo.pInfo));
            }
        }
        else
@@ -639,7 +632,7 @@ bool jfw_areEqualJavaInfo(JavaInfo const * pInfoA,JavaInfo const * pInfoB)
    return false;
}

javaFrameworkError jfw_getSelectedJRE(JavaInfo **ppInfo)
javaFrameworkError jfw_getSelectedJRE(std::unique_ptr<JavaInfo> *ppInfo)
{
    javaFrameworkError errcode = JFW_E_NONE;
    try
@@ -652,8 +645,7 @@ javaFrameworkError jfw_getSelectedJRE(JavaInfo **ppInfo)
        {
            OUString sJRE = jfw::BootParams::getJREHome();

            jfw::CJavaInfo aInfo;
            if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo))
            if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, ppInfo))
                != JFW_E_NONE)
                throw jfw::FrameworkException(
                    JFW_E_CONFIGURATION,
@@ -663,16 +655,13 @@ javaFrameworkError jfw_getSelectedJRE(JavaInfo **ppInfo)
                        " could not be recognized. Check the values and make sure that you "
                        "use a plug-in library that can recognize that JRE."));

            *ppInfo = aInfo.detach();
            return JFW_E_NONE;
        }

        const jfw::MergedSettings settings;
        jfw::CJavaInfo aInfo;
        aInfo.attach(settings.createJavaInfo());
        if (! aInfo)
        ppInfo->reset(settings.createJavaInfo());
        if (! ppInfo)
        {
            *ppInfo = nullptr;
            return JFW_E_NONE;
        }
        //If the javavendors.xml has changed, then the current selected
@@ -681,8 +670,10 @@ javaFrameworkError jfw_getSelectedJRE(JavaInfo **ppInfo)
        OString sUpdated = jfw::getElementUpdated();

        if (!sUpdated.equals(settings.getJavaInfoAttrVendorUpdate()))
        {
            ppInfo->reset();
            return JFW_E_INVALID_SETTINGS;
        *ppInfo = aInfo.detach();
        }
    }
    catch (const jfw::FrameworkException& e)
    {
@@ -705,7 +696,7 @@ javaFrameworkError jfw_isVMRunning(sal_Bool *bRunning)
    return JFW_E_NONE;
}

javaFrameworkError jfw_getJavaInfoByPath(rtl_uString *pPath, JavaInfo **ppInfo)
javaFrameworkError jfw_getJavaInfoByPath(rtl_uString *pPath, std::unique_ptr<JavaInfo> *ppInfo)
{
    javaFrameworkError errcode = JFW_E_NONE;
    try
@@ -744,12 +735,12 @@ javaFrameworkError jfw_getJavaInfoByPath(rtl_uString *pPath, JavaInfo **ppInfo)

            if (plerr == javaPluginError::NONE)
            {
                *ppInfo = pInfo;
                ppInfo->reset(pInfo);
                break;
            }
            else if(plerr == javaPluginError::FailedVersion)
            {//found JRE but it has the wrong version
                *ppInfo = nullptr;
                ppInfo->reset();
                errcode = JFW_E_FAILED_VERSION;
                break;
            }
@@ -759,7 +750,7 @@ javaFrameworkError jfw_getJavaInfoByPath(rtl_uString *pPath, JavaInfo **ppInfo)
            }
            OSL_ASSERT(false);
        }
        if (*ppInfo == nullptr && errcode != JFW_E_FAILED_VERSION)
        if (!*ppInfo && errcode != JFW_E_FAILED_VERSION)
            errcode = JFW_E_NOT_RECOGNIZED;
    }
    catch (const jfw::FrameworkException& e)
@@ -782,12 +773,12 @@ javaFrameworkError jfw_setSelectedJRE(JavaInfo const *pInfo)
        if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
            return JFW_E_DIRECT_MODE;
        //check if pInfo is the selected JRE
        JavaInfo *currentInfo = nullptr;
        std::unique_ptr<JavaInfo> currentInfo;
        errcode = jfw_getSelectedJRE( & currentInfo);
        if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
            return errcode;

        if (!jfw_areEqualJavaInfo(currentInfo, pInfo))
        if (!jfw_areEqualJavaInfo(currentInfo.get(), pInfo))
        {
            jfw::NodeJava node(jfw::NodeJava::USER);
            node.setJavaInfo(pInfo, false);
@@ -795,8 +786,6 @@ javaFrameworkError jfw_setSelectedJRE(JavaInfo const *pInfo)
            //remember that the JRE was selected in this process
            jfw::setJavaSelected();
        }

        delete currentInfo;
    }
    catch (const jfw::FrameworkException& e)
    {
diff --git a/stoc/source/javavm/javavm.cxx b/stoc/source/javavm/javavm.cxx
index 7c07453..41d786f 100644
--- a/stoc/source/javavm/javavm.cxx
+++ b/stoc/source/javavm/javavm.cxx
@@ -700,7 +700,7 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
    if (aId != aProcessId)
        return css::uno::Any();

    jfw::JavaInfoGuard info;
    std::unique_ptr<JavaInfo> info;
    while (!m_xVirtualMachine.is()) // retry until successful
    {
        stoc_javavm::JVM aJvm;
@@ -741,7 +741,7 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
        if (getenv("STOC_FORCE_NO_JRE"))
            errcode = JFW_E_NO_SELECT;
        else
            errcode = jfw_startVM(info.info, arOptions, index, & m_pJavaVm,
            errcode = jfw_startVM(info.get(), arOptions, index, & m_pJavaVm,
                                  & pMainThreadEnv);

        bool bStarted = false;
@@ -751,8 +751,8 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
        case JFW_E_NO_SELECT:
        {
            // No Java configured. We silently run the Java configuration
            info.clear();
            javaFrameworkError errFind = jfw_findAndSelectJRE(&info.info);
            info.reset();
            javaFrameworkError errFind = jfw_findAndSelectJRE(&info);
            if (getenv("STOC_FORCE_NO_JRE"))
                errFind = JFW_E_NO_JAVA_FOUND;
            if (errFind == JFW_E_NONE)
@@ -812,18 +812,18 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
            //we search another one. As long as there is a javaldx, we should
            //never come into this situation. javaldx checks always if the JRE
            //still exist.
            jfw::JavaInfoGuard aJavaInfo;
            if (JFW_E_NONE == jfw_getSelectedJRE(&aJavaInfo.info))
            std::unique_ptr<JavaInfo> aJavaInfo;
            if (JFW_E_NONE == jfw_getSelectedJRE(&aJavaInfo))
            {
                sal_Bool bExist = false;
                if (JFW_E_NONE == jfw_existJRE(aJavaInfo.info, &bExist))
                if (JFW_E_NONE == jfw_existJRE(aJavaInfo.get(), &bExist))
                {
                    if (!bExist
                        && ! (aJavaInfo.info->nRequirements & JFW_REQUIRE_NEEDRESTART))
                        && ! (aJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
                    {
                        info.clear();
                        info.reset();
                        javaFrameworkError errFind = jfw_findAndSelectJRE(
                            &info.info);
                            &info);
                        if (errFind == JFW_E_NONE)
                        {
                            continue;