Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions ModuleConfig.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ component {
* Fired when the module is registered and activated.
*/
function onLoad(){
// Bind Core JavaLoader
// Always bind Core JavaLoader; Loader.setup() will determine the actual strategy
binder.map( "jl@cbjavaloader" ).to( "#moduleMapping#.models.javaloader.JavaLoader" );

var isBoxLang = structKeyExists( server, "boxlang" );
// Duplicating so our final change won't affect the main module settings
var finalSettings = duplicate( settings );

Expand All @@ -67,11 +68,13 @@ component {
}
}

// Dynamic Proxy
arrayPrepend(
finalSettings.loadPaths,
variables.modulePath & "/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar"
);
// cfcdynamicproxy.jar is only needed for legacy CF runtimes, not BoxLang
if ( !isBoxLang ) {
arrayPrepend(
finalSettings.loadPaths,
variables.modulePath & "/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar"
);
}

// Load JavaLoader and class loading
wirebox.getInstance( "loader@cbjavaloader" ).setup( finalSettings );
Expand Down
51 changes: 50 additions & 1 deletion models/Loader.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ component accessors="true" singleton {
* Setup class loading
*/
function setup( required struct moduleSettings ){
// BoxLang 1.8.0+: use native class loading, skip JavaLoader entirely
if ( isBoxLangNative() ) {
var loadPaths = arguments.moduleSettings.loadPaths ?: [];
if ( !isArray( loadPaths ) ) {
loadPaths = listToArray( loadPaths );
}
if ( arrayLen( loadPaths ) ) {
getRequestClassLoader().addPaths( loadPaths );
}
return;
Comment thread
lmajano marked this conversation as resolved.
}

// verify we have it loaded
if ( not isJavaLoaderInScope() ) {
lock name="#variables.staticIDKey#" throwontimeout="true" timeout="30" type="exclusive" {
Expand Down Expand Up @@ -55,6 +67,9 @@ component accessors="true" singleton {
* Retrieves a reference to the java class. To create a instance, you must run init() on this object
*/
function create( required string className ){
if ( isBoxLangNative() ) {
return createObject( "java", arguments.className, getRequestClassLoader() );
}
return getJavaLoaderFromScope().create( argumentCollection = arguments );
}

Expand All @@ -65,6 +80,15 @@ component accessors="true" singleton {
* @filter.hint The directory filter
*/
function appendPaths( required string dirPath, string filter = "*.jar" ){
// BoxLang 1.8.0+: use native class loading
if ( isBoxLangNative() ) {
var newPaths = arrayOfJars( argumentCollection = arguments );
if ( arrayLen( newPaths ) ) {
getRequestClassLoader().addPaths( newPaths );
}
return;
}

// Convert paths to array of file locations
var qFiles = arrayOfJars( argumentCollection = arguments );
var iterator = qFiles.iterator();
Expand Down Expand Up @@ -99,6 +123,16 @@ component accessors="true" singleton {
* Get all the loaded URLs
*/
array function getLoadedURLs(){
// BoxLang 1.8.0+: get URLs directly from the request class loader
if ( isBoxLangNative() ) {
var loadedURLs = getRequestClassLoader().getURLs();
var returnArray = arrayNew( 1 );
for ( var url in loadedURLs ) {
arrayAppend( returnArray, url.toString() );
}
return returnArray;
}

var loadedURLs = getURLClassLoader().getURLs();
var returnArray = arrayNew( 1 );
var x = 1;
Expand All @@ -114,14 +148,22 @@ component accessors="true" singleton {
* Returns the java.net.URLClassLoader in case you need access to it
*/
any function getURLClassLoader(){
// BoxLang 1.8.0+: return the native request class loader
if ( isBoxLangNative() ) {
return getRequestClassLoader();
}
return getJavaLoaderFromScope().getURLClassLoader();
}

/**
* Get the Javaloader Version
*/
string function getVersion(){
return getJavaLoaderFromScope().getVersion();
if ( isJavaLoaderInScope() ) {
return getJavaLoaderFromScope().getVersion();
}
// BoxLang native mode: JavaLoader is not in scope; return the same version string
return "1.2";
}

/**
Expand Down Expand Up @@ -160,4 +202,11 @@ component accessors="true" singleton {
return structKeyExists( server, getstaticIDKey() );
}

/**
* Detects whether we are running on BoxLang, which always supports native dynamic class loading.
*/
private boolean function isBoxLangNative(){
return structKeyExists( server, "boxlang" );
}
Comment thread
lmajano marked this conversation as resolved.

}
4 changes: 3 additions & 1 deletion test-harness/tests/specs/LoaderTest.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" {
it( "should get loaded URLs", function(){
var loader = getLoader();
expect( loader.getLoadedURls() ).toBeArray();
expect( loader.getLoadedURLs() ).toHaveLength( 2 );
// BoxLang native: 1 path (helloworld.jar); CF/Lucee: 2 paths (+ cfcdynamicproxy.jar)
var expectedLen = structKeyExists( server, "boxlang" ) ? 1 : 2;
Comment thread
lmajano marked this conversation as resolved.
expect( loader.getLoadedURLs() ).toHaveLength( expectedLen );
} );

it( "should retrieve via custom DSL", function(){
Expand Down
Loading