|
Tcl Blend uses Tcl's package system to load in a shared library (or dll) that contains the C side of the Tcl/Java interface. The shared library starts up the Java Virtual machine and loads in the Java classes that implement the Java side of Tcl Blend.
When you type package require java
, the package system
reads each element of the auto_path
Tcl list to get
a directory name. The directory and any immediate subdirectories are
searched for pkgIndex.tcl
files. For more information, see
the Tcl
package
and
tclvars
manual pages
A typical pkgIndex.tcl
file includes Tcl commands
that do package specific setup and then package provide
is called, which tells the Tcl package system that a certain version
of the package is available.
In Tcl Blend, the pkgIndex.tcl
file usually resides
in the same directory as the libtclblend.so
shared library
and the tclblend.jar
Java class archive file.
pkgIndex.tcl
contains commands that set the
CLASSPATH
environment variable to include the current
directory, so that the Java Virtual Machine will find the Java classes
that implement the Java side of the Tcl Blend interface.
pkgIndex.tcl
then uses the Tcl
load
command to load the Tcl Blend shared library.
The Tcl load
command
is fairly platform specific.
Under Solaris, the is called libtclblend.so
and
your LD_LIBRARY_PATH
environment variable is used to
find the library.
Under Windows, the library is called tclblend.dll
, your
current directory is searched first and then the PATH
environment variable is searched.
The dynamic link library javai.dll could not be found in the specified path
c:\jdk1.1.6
, then be sure
that c:\jdk1.1.6\bin
is in your path.
Start
menu,
choose Settings
, then Control Panel
, then
choose the System
Icon. In the System window, choose
the Environment
tab and look under the
System Variables
section for the Path
entry.
Add c:\jdk1.1.6\bin
to the value of the path and click
Set
, then OK
.
package require java
fails to find the java package
If, under Windows, you compile and install Tcl8.0.3 yourself instead
of using the prebuilt binaries from Scriptics or the Tcl Blast CD,
then package require java
may fail to find the java package.
The problem is that if you install Tcl8.0.3 yourself, then the
Software\Scriptics\Tcl
Registry key is not set, so auto_path
is
not set to include the C:\Program Files\Tcl\lib
directory, instead it
only includes C:\Program Files\Tcl\lib\tcl8.0
.
If the Tcl Blend1.1 pkgIndex.tcl
file is in
C:\Program Files\Tcl\lib\tclblend1.1
,
then as a workaround, you
can append the parent directory to auto_path
:
lappend auto_path "C:/Program Files/Tcl/lib" package require javaAnother workaround is to set the
TCLLIBPATH
environment variable to C:\Program Files\Tcl\lib.
The problem stems from a bug in tcl8.0.3/library/init.tcl
,
and the bug has been fixed in the CVS sources at Scriptics.
could not find class tcl/lang/Interp.
LD_LIBRARY_PATH
variable needs to be set
to include the directory where your libtclblend.so
file resides.
~/.cshrc
, you would do something like:
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/usr/local/lib/tcl/tclblend
Also, check that libtclblend.so
is in a directory
listed in your auto_path
Tcl variable.
tcl_traceExec
variable to 1
, 2
,
or 3
to get tracing information about what commands
the Tcl interpreter is running. The Tcl
tclvars
man page contains further information about tcl_traceExec
CLASSPATH
.
truss
command to see what system calls tclsh
is making. The
output of truss
can be voluminous, but sometimes it is
the only way to track down path problems
JDK1.2
,
then you can set the tclblend_init
variable to tell the
JDK to go into verbose mode.
The follow command will cause the JDK to print information about what classes are being loaded, and what the JNI is doing:
set tclblend_init "-verbose:jni,class" package require javaTo see what sort of strings you can pass, type
java -help
and java -X
.
If you set tclblend_init
to help
, then
a short help message is returned.
Note that this functionality is only available with Tcl Blend 1.1 and JDK1.2
java.lang.Runtime
optionally includes support for tracing instructions
To turn on tracing, execute the following code:
set runtime [java::call Runtime getRuntime] $runtime traceInstructions TrueFor example:
% package require java 1.1 % set runtime [java::call Runtime getRuntime] java0x1 % $runtime traceInstructions True % set a [java::new java.util.GregorianCalendar] ED6660B0 0execute_java_constructor new tcl/lang/JavaNewCmd => tcl.lang.JavaNewCmd@ED66B748/ED757DC0 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B738/ED757DE0 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B720/ED757E40 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B710/ED757E80 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B838/ED757EC0 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B6F0/ED757F18 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B970/ED758008 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B948/ED7580B8 ED6660B0 0execute_java_constructor new java/lang/String => java.lang.String@ED66B920/ED758140 [etc]To turn of tracing of instructions, execute the following code:
$runtime traceInstructions FalseThe output of tracing instructions is very detailed, you may want to trace method calls instead.
java.lang.Runtime
optionally includes support for tracing Java Method Calls
To turn on tracing, execute the following code:
set runtime [java::call Runtime getRuntime] $runtime traceMethodCalls TrueFor example:
% package require java 1.1 % set runtime [java::call Runtime getRuntime] java0x1 % $runtime traceMethodCalls True # main [ 1] | < java/lang/Runtime.traceMethodCalls(Z)V returning # main [ 1] | < tcl/lang/Interp.setResult(Ltcl/lang/TclObject;)V returning % set a [java::new java.util.GregorianCalendar] # main [ 1] | < tcl/lang/CObject.incrRefCount(J)V returning # main [ 1] | < tcl/lang/CObject.incrRefCount(J)V returning # main [ 1] | < tcl/lang/CObject.getString(J)Ljava/lang/String; returning # main [ 1] | < tcl/lang/Interp.createCommand(Ljava/lang/String;Ltcl/lang/Command;)V returning # main [ 1] | < tcl/lang/TclList.listLength(JJ)I returning # main [ 1] | < tcl/lang/CObject.incrRefCount(J)V returning # main [ 1] | < tcl/lang/CObject.decrRefCount(J)V returning # main [ 1] | < tcl/lang/TclList.listLength(JJ)I returning # main [ 2] | | < tcl/lang/CObject.incrRefCount(J)V returning # main [ 1] | < tcl/lang/TclList.index(JI)Ltcl/lang/TclObject; returning # main [ 1] | < tcl/lang/CObject.getString(J)Ljava/lang/String; returning # main [ 1] | < tcl/lang/TclList.listLength(JJ)I returning # main [ 2] | | < tcl/lang/CObject.incrRefCount(J)V returning # main [ 1] | < tcl/lang/TclList.index(JI)Ltcl/lang/TclObject; returning # main [ 1] | < tcl/lang/CObject.getString(J)Ljava/lang/String; returning # main [ 1] | < tcl/lang/Interp.getVar(Ljava/lang/String;Ljava/lang/String;I)Ltcl/lang/TclObject; throwing tcl/lang/TclException # main [ 1] | < tcl/lang/CObject.getString(J)Ljava/lang/String; returning # main [ 1] | < tcl/lang/CObject.makeRef(JLtcl/lang/TclObject;)V returning # main [ 1] | < tcl/lang/CObject.decrRefCount(J)V returning # main [ 3] | | | < java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V returning # main [ 3] | | | < java/lang/Float.floatToIntBits(F)I returning # main [ 3] | | | < java/lang/Double.doubleToLongBits(D)J returning # main [ 1] | < tcl/lang/Interp.createCommand(Ljava/lang/String;Ltcl/lang/Command;)V returning # main [ 1] | < tcl/lang/Interp.setResult(Ltcl/lang/TclObject;)V returning java0x2 %To turn off tracing of method calls
$runtime traceMethodCalls False
www.javasoft.com
http://www.javasoft.com/jdc
- This is free to join, and a good place to search for information
about JNI bugs.
http://java.sun.com/products/jdk/1.2/docs/guide/jni/index.html
- Includes the JNI1.1 Specification and a FAQ
http://www.javasoft.com/docs/books/tutorial/native1.1/index.html
Last updated: 10/09/05
cxh at eecs