Here is the patch with the description of the problems solved in the patch.
Without the patch, my Java program causes an access violation when loading
TclBlend.

-- Jiang Wu
   [EMAIL PROTECTED]

-----Original Message-----
From: Jiang Wu [mailto:[EMAIL PROTECTED]] 
Sent: Tuesday, April 04, 2000 3:26 PM
To: [EMAIL PROTECTED]
Subject: [Tcl Java] The Mythical TclBlend Patch


Sorry folks, I never send the TclBlend patch to this mailing list.  I just
checked the Scriptics bug DB.  My bug report is there now.  It is number
4352.  The report does not show the patch.  I copied the bug report at the
end of this email.  The patch is also attached to the email.  The patch
allows one to write a Java based shell using native TCL through TclBlend.  I
will post my modified Jacl shell later this week that you can use to try out
the patch.

-- Jiang Wu
   [EMAIL PROTECTED]


============================================================================
==============
TR#4352
 
Help | New Bug Report | Simple Search | Advanced Search | Product Summary |
Component Summary | Settings

Unable to start TclBlend from Java
TclBlend Java Interface
TclBlend Java Interface - TclBlend Java Interface
Found in Version: 1.2.6 

Subject: Unable to start TclBlend from Java 
Name:
Jiang Wu

ReproducibleScript:

The following Java program will crash.  

---------- Java program -----------------
import tcl.lang.*;

public class Shell {
    public static void main (String args[]) {
        Interp interp = new Interp();
    }
};


ObservedBehavior:

If one tries to start a native TCL
interpreter inside a Java process using TclBlend, the program produces an
access violation.  Most of the TclBlend functions expect TclBlend_Init() to
be called first before "new Interp()" can function properly.  However, if a
Java program tries to load TclBlend instead of a native TCL program trying
to load TclBlend, TclBlend_Init() is never called.

In particular, the above program will trigger an access violation in the
following location in /tcljava/src/native/javaInterp.c:

jlong JNICALL
Java_tcl_lang_Interp_create(
    JNIEnv *env,                /* Java environment. */
    jobject interpObj)          /* Handle to Interp object. */
{
    jlong lvalue;
    Tcl_Interp *interp;
    JNIEnv *oldEnv;

    JAVA_LOCK();      /* !!!!!!! this line triggers an access violation
!!!!!! */
    /* ... stuff to create the native TCL interpreter ... */
    JAVA_UNLOCK();
    return lvalue;
}

DesiredBehavior:

One should be able to embed a native TCL
interpreter inside a Java program.  One should be able to write a tclsh like
program in Java using TclBlend and the native TCL library.  The embeded
native TCL interpreter in a Java program should behave the same a native TCL
interpreter running inside a C program.

Patch: Look in /home/bugs/tclblend under this bug number.

Patch files:  java.h, javaCmd.c, javaInterp.c, Notifier.java

 


----------------------------------------------------------------------------
----

Comments
Comments on: Unable to start TclBlend from Java
The changes in the patch was tested using JDK 1.2.2,
Tcl 8.2.3 as well as the multi-threaded version of Tcl 8.2.3 on Windows NT
4.  The changes fix the following 4 problems that prevented a native TCL
interpreter from being embeded inside a Java program.

1. In javaInterp.c, if TclBlend is started inside a JVM,
Java_tcl_lang_Interp_create() function uses an uninitialized global pointer,
java.NativeLock.  The fix is to use a separate TCL mutex instead of the Java
mutex used in the JAVA_LOCK macro to protect TclBlend global data structures
used to store JVM information during TclBlend initialization.  The change
touches java.h, javaCmd.h and javaInterp.c.  TclBlend_Init() is also changed
to use the new mutex when it sets up the globals.  The TCL mutex should only
be used if TclBlend is to be linked with the muti-threaded version of TCL.
The modified code uses the macro "TCL_THREADS" to determine whether to use
the TCL mutex or not.  This macro should be define appropriately during the
compilation process.  For non-threaded TCL, no mutex is used.

2. In the Java class Notifier, the method "hasEvent()" always returns true
if it is called within "serviceEvent()".  This can happen if
"Notifier.doOneEvent()" triggers a "serviceEvent()" to eval "vwait" or
"update" TCL commands.  When this senario happens, the program goes into a
busy infinite loop calling "hasEvent(), doOneEvent(), hasEvent(),
doOneEvent(), ...".  "hasEvent()" is modified such that it skips all events
on the event list that is currently being processed at the moment
"hasEvent()" is invoked.

3. In the Java class Notifier, a synchronization deadlock can happen between
"serviceEvent()" and "queueEvent()".  If the main thread for the interpreter
is executing a "vwait" inside a "serviceEvent()", it will block any other
thread from calling "queueEvent()" because the two methods are synchronized
on the Notifier instance object.  The "vwait" command will cause the main
thread to wait inside TclBlend native code.  As a result, it does not
relinquish the lock on the Notifier instance object.  The fix is to remove
the use of the "synchronized" keyword.  Instead, use a private local mutex
object to protect the access to the event list inside the Nofier object.
When the code synchronizes on the local mutex object, never calls another
other methods that may block or uses other mutex.  This prevents deadlock.

4. In the class Notifier, the method "deleteEvents()" has a bug that it does
not properly set the "lastEvent" and "markerEvent" pointers when an event
from the middle of the event list is removed.  The fix is to move the event
deletion code from "serviceEvent()" into "deleteEvents()".  "serviceEvent()"
now uses "deleteEvents()" to delete processed event.  This reduces the
chances of error by removing redundant codes.



-- Jennifer Hom on March 17, 2000 10:50 PM


Type Defect 
State New 
Severity Critical: Major defect, no workaround 
Priority Unknown - Not yet prioritized 
Category Other 
OS Windows NT Windows NT 4 Dell Pentium II 450 Mhz 
Found in Version 1.2.6 
Fixed Date 2000-03-17 00:00:00 



-----Original Message-----
From: W. John Guineau [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, May 24, 2000 5:49 PM
To: Mo DeJong
Cc: Jiang Wu; [EMAIL PROTECTED]
Subject: RE: [Tcl Java] RE: [Tcl Java] Tcl Blend vs JACL

Hmm, this patch wouldn't happen to fix the following odd error I'm currently
chasing (below), would it?

=========================================
C:\JTCCSRoot\ui\Automation>set bld=debug

C:\JTCCSRoot\ui\Automation>set
path=c:\jdk1.3\jre\bin;c:\jdk1.3\jre\bin\classic;C:\tcl\tcl8.3.1\win\debug;c
:\tcl\tcl8.3.1\lib\tclblend;.;C:\WINNT\system32;C:\WINNT;

C:\JTCCSRoot\ui\Automation>set
cp=C:\jdk1.3\jre\lib\rt.jar;.\classes;c:\tcl\tcl8.3.1\lib\tcljava.jar;c:\tcl
\tcl8.3.1\lib\tclblend.jar

C:\JTCCSRoot\ui\Automation>java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

C:\JTCCSRoot\ui\Automation>java -classpath
C:\jdk1.3\jre\lib\rt.jar;.\classes;c:
\tcl\tcl8.3.1\lib\tcljava.jar;c:\tcl\tcl8.3.1\lib\tclblend.jar
scriptmanager.Scr
iptManager
Exception in thread "main" java.lang.NullPointerException
        at tcl.lang.Interp.create(Native Method)
        at tcl.lang.Interp.<init>(Interp.java:130)
        at scriptmanager.ScriptManager.main(ScriptManager.java:24)
EXP: tcl.lang.TclRuntimeError: could not find class java/lang/Object.
Check that your path includes the directory where tclblend.dll resides.
Try looking in the directories under the value of tcl_library,
currently: Currently, the CLASSPATH environment variable is not set.
=========================================


tclblend.patch

Reply via email to