You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/10/19 20:14:16 UTC

svn commit: r1533804 - in /subversion/trunk: ./ subversion/bindings/javahl/native/

Author: brane
Date: Sat Oct 19 18:14:16 2013
New Revision: 1533804

URL: http://svn.apache.org/r1533804
Log:
Fix some wrong assumptions in JavaHL that led to wrong implementation,
and simplify JNI environment handling.

Amongst other things, the assumption that looking at a Java exception
will remove it from the environment was incorrect.

* build.conf (libsvnjavahl): There are no C files in JavaHL.

* subversion/bindings/javahl/native/JNIThreadData.cpp,
  subversion/bindings/javahl/native/JNIThreadData.h: Removed, unused.
* subversion/bindings/javahl/native/libsvnjavahl.la.c: Removed.
   Implementation moved to JNIUtil.cpp.

* subversion/bindings/javahl/native/SVNClient.cpp,
  subversion/bindings/javahl/native/JNIStackElement.cpp,
  subversion/bindings/javahl/native/JNIStackElement.h:
   Removed all references to JNIThreadData.

* subversion/bindings/javahl/native/JNIUtil.h:
   Removed all references to JNIThreadData.
  (JNIUtil::getFormatBuffer, JNIUtil::formatBufferSize,
   JNIUtil::g_initFormatBuffer, JNIUtil::setEnv,
   JNIUtil::setExceptionThrown): Removed.
  (JNIUtil::isExceptionThrown(), JNIUtil::isJavaExceptionThrown()):
   Changed to simple inline implementations.

* subversion/bindings/javahl/native/JNIUtil.cpp:
   Removed implementaitons that were removed from the class declaration.
   (JNI_OnLoad): Remember the VM pointer.
   (JNIUtil::getEnv): Get an environemnt from the JVM.

Removed:
    subversion/trunk/subversion/bindings/javahl/native/JNIThreadData.cpp
    subversion/trunk/subversion/bindings/javahl/native/JNIThreadData.h
    subversion/trunk/subversion/bindings/javahl/native/libsvnjavahl.la.c
Modified:
    subversion/trunk/build.conf
    subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.cpp
    subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.h
    subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp
    subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
    subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp

Modified: subversion/trunk/build.conf
URL: http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Sat Oct 19 18:14:16 2013
@@ -686,7 +686,7 @@ type = lib
 path = subversion/bindings/javahl/native
 libs = libsvn_repos libsvn_client libsvn_wc libsvn_ra libsvn_delta libsvn_diff 
        libsvn_subr libsvn_fs aprutil apriconv apr java-sdk
-sources = *.cpp *.c
+sources = *.cpp
 add-deps = $(javahl_java_DEPS) $(javahl_callback_javah_DEPS)
            $(javahl_remote_javah_DEPS) $(javahl_types_javah_DEPS)
            $(javahl_util_javah_DEPS) $(javahl_javah_DEPS)

Modified: subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.cpp?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.cpp Sat Oct 19 18:14:16 2013
@@ -27,7 +27,6 @@
 #include "JNIStackElement.h"
 #include "JNIUtil.h"
 #include "JNIStringHolder.h"
-#include "JNIThreadData.h"
 #include <apr_strings.h>
 
 /**
@@ -74,7 +73,7 @@ JNIStackElement::JNIStackElement(JNIEnv 
 
           // Copy the result to a buffer.
           JNIStringHolder name(reinterpret_cast<jstring>(oStr));
-          strncat(m_objectID, name, JNIUtil::formatBufferSize -1);
+          strncat(m_objectID, name, sizeof(m_objectID) - 1);
           env->DeleteLocalRef(oStr);
         }
 
@@ -86,8 +85,8 @@ JNIStackElement::JNIStackElement(JNIEnv 
       m_method = method;
 
       // Generate the log message.
-      char *buffer = JNIUtil::getFormatBuffer();
-      apr_snprintf(buffer, JNIUtil::formatBufferSize,
+      char buffer[2048];
+      apr_snprintf(buffer, sizeof(buffer),
                    "entry class %s method %s object %s", m_clazz, m_method,
                    m_objectID);
       JNIUtil::logMessage(buffer);
@@ -110,11 +109,10 @@ JNIStackElement::~JNIStackElement()
   if (m_clazz != NULL)
     {
       // Generate a log message.
-      char *buffer = JNIUtil::getFormatBuffer();
-      apr_snprintf(buffer, JNIUtil::formatBufferSize,
+      char buffer[2048];
+      apr_snprintf(buffer, sizeof(buffer),
                    "exit class %s method %s object %s", m_clazz,
                    m_method, m_objectID);
       JNIUtil::logMessage(buffer);
     }
-  JNIThreadData::popThreadData();
 }

Modified: subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.h?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIStackElement.h Sat Oct 19 18:14:16 2013
@@ -73,7 +73,7 @@ class JNIStackElement
    * A buffer for the result for jthis.toString to identify the
    * object.
    */
-  char m_objectID[JNIUtil::formatBufferSize];
+  char m_objectID[2048];
 };
 
 #endif // JNISTACKELEMENT_H

Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp Sat Oct 19 18:14:16 2013
@@ -68,10 +68,10 @@ extern "C" {
 #include "SVNBase.h"
 #include "JNIMutex.h"
 #include "JNICriticalSection.h"
-#include "JNIThreadData.h"
 #include "JNIStringHolder.h"
 #include "Pool.h"
 
+
 // Static members of JNIUtil are allocated here.
 apr_pool_t *JNIUtil::g_pool = NULL;
 std::list<SVNBase*> JNIUtil::g_finalizedObjects;
@@ -81,10 +81,39 @@ JNIMutex *JNIUtil::g_configMutex = NULL;
 bool JNIUtil::g_initException;
 bool JNIUtil::g_inInit;
 JNIEnv *JNIUtil::g_initEnv;
-char JNIUtil::g_initFormatBuffer[formatBufferSize];
 int JNIUtil::g_logLevel = JNIUtil::noLog;
 std::ofstream JNIUtil::g_logStream;
 
+namespace {
+JavaVM *g_jvm = NULL;
+} // anonymous namespace
+
+extern "C" JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *jvm, void*)
+{
+  g_jvm = jvm;
+  return JNI_VERSION_1_2;
+}
+
+extern "C" JNIEXPORT void JNICALL
+JNI_OnUnload(JavaVM*, void*)
+{}
+
+/**
+ * Return the JNI environment to use
+ * @return the JNI environment
+ */
+JNIEnv *JNIUtil::getEnv()
+{
+  // During init -> look into the global variable.
+  if (g_inInit)
+    return g_initEnv;
+
+  void* penv;
+  g_jvm->GetEnv(&penv, JNI_VERSION_1_2);
+  return static_cast<JNIEnv*>(penv);
+}
+
 /**
  * Initialize the environment for all requests.
  * @param env   the JNI environment for this request
@@ -94,9 +123,6 @@ bool JNIUtil::JNIInit(JNIEnv *env)
   // Clear all standing exceptions.
   env->ExceptionClear();
 
-  // Remember the env parameter for the remainder of the request.
-  setEnv(env);
-
   // Lock the list of finalized objects.
   JNICriticalSection cs(*g_finalizedObjectsMutex) ;
   if (isExceptionThrown())
@@ -361,14 +387,6 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
   if (isExceptionThrown())
     return false;
 
-  // initialized the thread local storage
-  if (!JNIThreadData::initThreadData())
-    return false;
-
-  setEnv(env);
-  if (isExceptionThrown())
-    return false;
-
   g_initEnv = NULL;
   g_inInit = false;
 
@@ -399,8 +417,6 @@ void JNIUtil::raiseThrowable(const char 
     return;
 
   env->ThrowNew(clazz, message);
-  setExceptionThrown();
-  env->DeleteLocalRef(clazz);
 }
 
 void
@@ -825,80 +841,15 @@ void JNIUtil::enqueueForDeletion(SVNBase
  */
 void JNIUtil::handleAPRError(int error, const char *op)
 {
-  char *buffer = getFormatBuffer();
-  if (buffer == NULL)
-    return;
+  char buffer[2048];
 
-  apr_snprintf(buffer, formatBufferSize,
+  apr_snprintf(buffer, sizeof(buffer),
                _("an error occurred in function %s with return value %d"),
                op, error);
 
   throwError(buffer);
 }
 
-/**
- * Return if an exception has been detected.
- * @return a exception has been detected
- */
-bool JNIUtil::isExceptionThrown()
-{
-  // During init -> look in the global member.
-  if (g_inInit)
-    return g_initException;
-
-  // Look in the thread local storage.
-  JNIThreadData *data = JNIThreadData::getThreadData();
-  return data == NULL || data->m_exceptionThrown;
-}
-
-/**
- * Store the JNI environment for this request in the thread local
- * storage.
- * @param env   the JNI environment
- */
-void JNIUtil::setEnv(JNIEnv *env)
-{
-  JNIThreadData::pushNewThreadData();
-  JNIThreadData *data = JNIThreadData::getThreadData();
-  data->m_env = env;
-  data->m_exceptionThrown = false;
-}
-
-/**
- * Return the JNI environment to use
- * @return the JNI environment
- */
-JNIEnv *JNIUtil::getEnv()
-{
-  // During init -> look into the global variable.
-  if (g_inInit)
-    return g_initEnv;
-
-  // Look in the thread local storage.
-  JNIThreadData *data = JNIThreadData::getThreadData();
-  return data->m_env;
-}
-
-/**
- * Check if a Java exception has been thrown.
- * @return is a Java exception has been thrown
- */
-bool JNIUtil::isJavaExceptionThrown()
-{
-  JNIEnv *env = getEnv();
-  if (env->ExceptionCheck())
-    {
-      // Retrieving the exception removes it so we rethrow it here.
-      jthrowable exp = env->ExceptionOccurred();
-      env->ExceptionDescribe();
-      env->Throw(exp);
-      env->DeleteLocalRef(exp);
-      setExceptionThrown();
-      return true;
-    }
-  return false;
-}
-
 namespace {
 const char* known_exception_to_cstring(apr_pool_t* pool)
 {
@@ -984,25 +935,6 @@ jstring JNIUtil::makeJString(const char 
   return env->NewStringUTF(txt);
 }
 
-void
-JNIUtil::setExceptionThrown(bool flag)
-{
-  if (g_inInit)
-    {
-      // During global initialization, store any errors that occur
-      // in a global variable (since thread-local storage may not
-      // yet be available).
-      g_initException = flag;
-    }
-  else
-    {
-      // When global initialization is complete, thread-local
-      // storage should be available, so store the error there.
-      JNIThreadData *data = JNIThreadData::getThreadData();
-      data->m_exceptionThrown = flag;
-    }
-}
-
 /**
  * Initialite the log file.
  * @param level the log level
@@ -1026,23 +958,6 @@ void JNIUtil::initLogFile(int level, jst
 }
 
 /**
- * Returns a buffer to format error messages.
- * @return a buffer for formating error messages
- */
-char *JNIUtil::getFormatBuffer()
-{
-  if (g_inInit) // during init -> use the global buffer
-    return g_initFormatBuffer;
-
-  // use the buffer in the thread local storage
-  JNIThreadData *data = JNIThreadData::getThreadData();
-  if (data == NULL) // if that does not exists -> use the global buffer
-    return g_initFormatBuffer;
-
-  return data->m_formatBuffer;
-}
-
-/**
  * Returns the current log level.
  * @return the log level
  */
@@ -1182,8 +1097,6 @@ void JNIUtil::throwNullPointerException(
     return;
 
   env->ThrowNew(clazz, message);
-  setExceptionThrown();
-  env->DeleteLocalRef(clazz);
 }
 
 svn_error_t *JNIUtil::preprocessPath(const char *&path, apr_pool_t *pool)

Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h Sat Oct 19 18:14:16 2013
@@ -73,17 +73,18 @@ class JNIUtil
   static apr_time_t getDate(jobject jdate);
   static void logMessage(const char *message);
   static int getLogLevel();
-  static char *getFormatBuffer();
   static void initLogFile(int level, jstring path);
   static jstring makeJString(const char *txt);
-  static bool isJavaExceptionThrown();
   static JNIEnv *getEnv();
-  static void setEnv(JNIEnv *);
 
   /**
    * @return Whether any Throwable has been raised.
    */
-  static bool isExceptionThrown();
+  static bool isExceptionThrown() { return isJavaExceptionThrown(); }
+  static bool isJavaExceptionThrown()
+    {
+      return getEnv()->ExceptionCheck();
+    }
 
   static void handleAPRError(int error, const char *op);
 
@@ -149,7 +150,6 @@ class JNIUtil
   static bool JNIGlobalInit(JNIEnv *env);
   static bool JNIInit(JNIEnv *env);
   static bool initializeJNIRuntime();
-  enum { formatBufferSize = 2048 };
   enum { noLog, errorLog, exceptionLog, entryLog } LogLevel;
 
   /**
@@ -161,11 +161,6 @@ class JNIUtil
   static void wrappedHandleSVNError(svn_error_t *err);
   static void putErrorsInTrace(svn_error_t *err,
                                std::vector<jobject> &stackTrace);
-  /**
-   * Set the appropriate global or thread-local flag that an exception
-   * has been thrown to @a flag.
-   */
-  static void setExceptionThrown(bool flag = true);
 
   /**
    * The log level of this module.
@@ -210,11 +205,6 @@ class JNIUtil
   static JNIEnv *g_initEnv;
 
   /**
-   * Fuffer the format error messages during initialization.
-   */
-  static char g_initFormatBuffer[formatBufferSize];
-
-  /**
    * The stream to write log messages to.
    */
   static std::ofstream g_logStream;

Modified: subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp?rev=1533804&r1=1533803&r2=1533804&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp Sat Oct 19 18:14:16 2013
@@ -1343,10 +1343,10 @@ jstring SVNClient::getVersionInfo(const 
         }
         else
         {
-            char *message = JNIUtil::getFormatBuffer();
-            apr_snprintf(message, JNIUtil::formatBufferSize,
+            char buffer[2048];
+            apr_snprintf(buffer, sizeof(buffer),
                          _("'%s' not versioned, and not exported\n"), path);
-            return JNIUtil::makeJString(message);
+            return JNIUtil::makeJString(buffer);
         }
     }