/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
*/
// Load a class. A map from pairs of (classPath, name) to pairs of weak Java // references to (ClassLoader, Class) is maintained, so that a class is only // loaded once. // // It may happen that the weak reference to the ClassLoader becomes null while // the reference to the Class remains non-null (in case the Class was actually // loaded by some parent of the ClassLoader), in which case the ClassLoader is // resurrected (which cannot cause any classes to be loaded multiple times, as // the ClassLoader is no longer reachable, so no classes it has ever loaded are // still reachable). // // Similarly, it may happen that the weak reference to the Class becomes null // while the reference to the ClassLoader remains non-null, in which case the // Class is simply re-loaded. // // This code is close to the implementation of jvmaccess::ClassPath::loadClass // in jvmaccess/classpath.hxx, but not close enough to avoid the duplication. // // If false is returned, a (still pending) JNI exception occurred. bool loadClass(
Reference< XComponentContext > const & context, JNIEnv& environment,
OUString const & classPath, OUString const & name,
LocalRef< jobject > * classLoaderPtr, LocalRef< jclass > * classPtr)
{
OSL_ASSERT(classLoaderPtr != nullptr); // For any jweak entries still present in the map upon destruction, // DeleteWeakGlobalRef is not called (which is a leak): static ClassMapData classMapData;
osl::MutexGuard g(classMapData.mutex);
ClassMap::iterator i(classMapData.map.begin());
LocalRef< jobject > cloader(environment);
LocalRef< jclass > cl(environment); // Prune dangling weak references from the list while searching for a match, // so that the list cannot grow unbounded: for (; i != classMapData.map.end();)
{
LocalRef< jobject > classLoader( environment ); if ( !getLocalFromWeakRef( i->classLoader, classLoader ) ) returnfalse;
if ( !classLoader.is() && !classObject.is() )
{
i = classMapData.map.erase(i);
} elseif ( i->classPath == classPath && i->className == name )
{
cloader.set( classLoader.release() );
cl.set( classObject.release() ); break;
} else
{
++i;
}
} if ( !cloader.is() || !cl.is() )
{ if ( i == classMapData.map.end() )
{ // Push a new ClassMapEntry (which can potentially fail) before // loading the class, so that it never happens that a class is // loaded but not added to the map (which could have effects on the // JVM that are not easily undone). If the pushed ClassMapEntry is // not used after all (return false, etc.) it will be pruned on next // call because its classLoader/classObject are null:
classMapData.map.emplace_back(classPath, name);
i = std::prev(classMapData.map.end());
}
jclass java_sql_Connection::getMyClass() const
{ // the class must be fetched only once, therefore static if( !theClass )
theClass = findMyClass("java/sql/Connection"); return theClass;
}
SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!"); static jmethodID mID(nullptr);
callObjectMethod(t.pEnv,"getTypeMap","()Ljava/util/Map;", mID); // WARNING: the caller becomes the owner of the returned pointer return nullptr;
}
Any SAL_CALL java_sql_Connection::getWarnings( )
{
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
SDBThreadAttach t; static jmethodID mID(nullptr);
jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID); // WARNING: the caller becomes the owner of the returned pointer if( out )
{
java_sql_SQLWarning_BASE warn_base(t.pEnv, out);
SQLException aAsException( java_sql_SQLWarning( warn_base, *this ) );
// translate to warning
SQLWarning aWarning(aAsException.Message, aAsException.Context, aAsException.SQLState,
aAsException.ErrorCode, aAsException.NextException);
void java_sql_Connection::loadDriverFromProperties( const OUString& _sDriverClass, const OUString& _sDriverClassPath, const Sequence< NamedValue >& _rSystemProperties )
{ // first try if the jdbc driver is already registered at the driver manager
SDBThreadAttach t; try
{ if ( !object )
{ if ( !lcl_setSystemProperties_nothrow( getLogger(), *t.pEnv, _rSystemProperties ) )
ThrowLoggedSQLException( getLogger(), t.pEnv, *this );
m_pDriverClassLoader.reset();
// here I try to find the class for jdbc driver
java_sql_SQLException_BASE::st_getMyClass();
java_lang_Throwable::st_getMyClass();
if ( _sDriverClass.isEmpty() )
{
m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_DRIVER_CLASS );
::dbtools::throwGenericSQLException(
lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
*this
);
} else
{
m_aLogger.log( LogLevel::INFO, STR_LOG_LOADING_DRIVER, _sDriverClass ); // the driver manager holds the class of the driver for later use
std::unique_ptr< java_lang_Class > pDrvClass; if ( _sDriverClassPath.isEmpty() )
{ // if forName didn't find the class it will throw an exception
pDrvClass.reset(java_lang_Class::forName(_sDriverClass));
} else
{
LocalRef< jclass > driverClass(t.env());
LocalRef< jobject > driverClassLoader(t.env());
bool java_sql_Connection::construct(const OUString& url, const Sequence< PropertyValue >& info)
{
{ // initialize the java vm
::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM(m_xContext); if ( !xTest.is() )
throwGenericSQLException(STR_NO_JAVA,*this);
}
SDBThreadAttach t;
SDBThreadAttach::addRef(); // will be released in dtor if ( !t.pEnv )
throwGenericSQLException(STR_NO_JAVA,*this);
OUString sGeneratedValueStatement; // contains the statement which should be used when query for automatically generated values bool bAutoRetrievingEnabled = false; // set to <TRUE/> when we should allow to query for generated values
OUString sDriverClassPath,sDriverClass;
Sequence< NamedValue > aSystemProperties;
jobject out = nullptr; // In some cases (e.g., // connectivity/source/drivers/hsqldb/HDriver.cxx:1.24 // l. 249) the JavaDriverClassPath contains multiple jars, // as creating the JavaDriverClass instance requires // (reflective) access to those other jars. Now, if the // JavaDriverClass is actually loaded by some parent class // loader (e.g., because its jar is also on the global // class path), it would still not have access to the // additional jars on the JavaDriverClassPath. Hence, the // JavaDriverClassPath class loader is pushed as context // class loader around the JavaDriverClass instance // creation: // #i82222# / 2007-10-15
{
ContextClassLoaderScope ccl( t.env(), getDriverClassLoader(), getLogger(), *this );
out = t.pEnv->CallObjectMethod( m_pDriverobject, mID, args[0].l,args[1].l );
pProps.reset();
ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
}
if ( !out )
m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_SYSTEM_CONNECTION );
if ( out )
object = t.pEnv->NewGlobalRef( out );
if ( object )
m_aLogger.log( LogLevel::INFO, STR_LOG_GOT_JDBC_CONNECTION, url );
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.