[tcljava-dev] package unknown - looking for pkgIndex.tcl in the java classpath
Brought to you by:
mdejong
|
From: Christian B. <chr...@lf...> - 2007-10-08 08:03:00
|
Hello,
I have written for a project a patch for tclPkgUnknown that allows
loading a jar bundled package (or any other package available in the
classpath) with a root pkgIndex.tcl using 'package require foo'. It's
implemented by looking first for root classpath resources named
'pkgIndex.tcl' and sourcing them via 'source -url' (it uses the commands
from the java package). The patch itself is a procedure named
jaclPkgUnknown which delegates to the standard tclPkgUnknown found in
init.tcl for scanning the auto_path directories as well. You can use the
classpath loading by specifying this proc as the package unknown script.
The proc is as follows:
# jaclPkgUnknown --
#
# Tcl/Java specific procedure for the "package unknown" function. It is
# invoked when a package that's needed can't be found. It scans first the
# current thread's ContextClassLoader looking for root resources named
# pkgIndex.tcl and sources any such resources that are found to setup the
# package database. Subsequently it calls the standard unknown procedure
# 'tclPkgUnknown' which scans the auto_path directories as well.
#
# Arguments:
# name Name of desired package. Not used.
# version Version of desired package. Not used.
# exact Either "-exact" or omitted. Not used.
proc jaclPkgUnknown {name version {exact {}}} {
package require java
global dir
if {[info exists dir]} {
set save_dir $dir
}
# Looking for /pkgIndex.tcl via the the thread's ContextClassLoader
set tccl [[java::call Thread currentThread] getContextClassLoader]
set urls [$tccl getResources pkgIndex.tcl]
while {[$urls hasMoreElements]} {
set url [[$urls nextElement] toString]
if {[string first "file:" $url] == 0} {
# Extract the path from the file url and set dir to its parent
set filename [string range $url 5 [string length $url]]
set dir [file dirname $filename]
} elseif {[string first "jar:file:" $url] == 0} {
# Set dir to a root resource location
set dir "resource:/"
} else {
tclLog "can't read package index from url \"$url\": protocol
not supported"
continue
}
if [catch {source -url $url} msg] {
error "error reading package index file from url \"$url\": $msg"
}
}
# Delegate to standard unknown procedure
tclPkgUnknown $name $version $exact
if {[info exists save_dir]} {
set dir $save_dir
} else {
unset dir
}
}
The proc doesn't function if the sourced pkgIndex.tcl (found in a jar
file) uses file globbing since dir is set to resource:/.
I hope the patch will be useful.
Greetings from Munich,
Christian
|