Skip to content

Commit a30a26a

Browse files
committed
Merge branch 'feature/switchArguments' into develop
2 parents 5d8944d + 5eca62d commit a30a26a

3 files changed

Lines changed: 124 additions & 16 deletions

File tree

javaloader/JavaLoader.cfc

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ Purpose: Utlitity class for loading Java Classes
104104

105105
<cffunction name="switchThreadContextClassLoader" hint="Sometimes you will need to switch out the ThreadContextClassLoader with the classloader used by JavaLoader.<br/>
106106
It has :
107-
switchThreadContextClassLoader(function object, [classLoader=getURLClassLoader()])
108-
switchThreadContextClassLoader(function name, [classLoader=getURLClassLoader()])
109-
switchThreadContextClassLoader(object, function name, [classLoader=getURLClassLoader()])
107+
switchThreadContextClassLoader(function object, [struct function arguments], [classLoader=getURLClassLoader()])
108+
switchThreadContextClassLoader(function name, [struct function arguments], [classLoader=getURLClassLoader()])
109+
switchThreadContextClassLoader(object, function name, [struct function arguments], [classLoader=getURLClassLoader()])
110110
This method can be used in 3 different ways:
111111
<ol>
112112
<li>Pass it the UDF itself</li>
@@ -116,21 +116,61 @@ Purpose: Utlitity class for loading Java Classes
116116
access="public" returntype="any" output="false">
117117
<cfscript>
118118
var local = {};
119+
var func = 0; //need this as cf8 doesn't like the structure with functions.
119120
var System = createObject("java", "java.lang.System");
120121
var Thread = createObject("java", "java.lang.Thread");
121122
var currentClassloader = Thread.currentThread().getContextClassLoader();
122-
123-
if(structCount(arguments) == 2 && !isSimpleValue(arguments[2]))
124-
{
125-
classLoader = arguments[2];
123+
var classLoader = "";
124+
125+
if (structCount(arguments) == 4)
126+
{
127+
// the last 2 arguments are the function arguments and class loader
128+
classLoader = arguments[4];
129+
local.funcArgs = arguments[3];
130+
}
131+
else if (structCount(arguments) == 3)
132+
{
133+
// 2nd argument could be classloader or function arguments
134+
if (isInstanceOf(arguments[2],"java.lang.ClassLoader"))
135+
{
136+
classLoader = arguments[2];
137+
}
138+
else if (isStruct(arguments[2]))
139+
{
140+
local.funcArgs = arguments[2];
141+
}
142+
143+
// 3rd argument could be classloader or function arguments
144+
if (isInstanceOf(arguments[3],"java.lang.ClassLoader"))
145+
{
146+
classLoader = arguments[3];
147+
}
148+
else if (isStruct(arguments[3]))
149+
{
150+
local.funcArgs = arguments[3];
151+
}
152+
}
153+
else if (structCount(arguments) == 2)
154+
{
155+
// the 2nd argument could be a class loader or function arguments
156+
if (isInstanceOf(arguments[2],"java.lang.ClassLoader"))
157+
{
158+
classLoader = arguments[2];
159+
}
160+
else if (isStruct(arguments[2]))
161+
{
162+
local.funcArgs = arguments[2];
163+
}
126164
}
127-
else if(structCount(arguments) == 3)
165+
166+
if (!structKeyExists(local,"funcArgs"))
128167
{
129-
classLoader = arguments[3];
168+
local.funcArgs = {};
130169
}
131-
else //assume we are still in JL
170+
171+
if (isSimpleValue(classLoader))
132172
{
133-
classLoader = getURLClassLoader();
173+
classLoader = getURLClassLoader();
134174
}
135175
</cfscript>
136176

@@ -140,14 +180,14 @@ Purpose: Utlitity class for loading Java Classes
140180
</cfscript>
141181

142182
<cfif isSimpleValue(arguments[1])>
143-
<cfinvoke method="#arguments[1]#" returnvariable="local.return" />
183+
<cfinvoke method="#arguments[1]#" returnvariable="local.return" argumentCollection="#local.funcArgs#" />
144184
<cfelseif isCustomFunction(arguments[1])>
145185
<cfscript>
146-
local.func = arguments[1];
147-
local.return = local.func();
186+
func = arguments[1];
187+
local.return = func(argumentCollection = local.funcArgs);
148188
</cfscript>
149189
<cfelseif isObject(arguments[1]) AND isSimpleValue(arguments[2])>
150-
<cfinvoke component="#arguments[1]#" method="#arguments[2]#" returnvariable="local.return" />
190+
<cfinvoke component="#arguments[1]#" method="#arguments[2]#" returnvariable="local.return" argumentCollection="#local.funcArgs#" />
151191
<cfelse>
152192
<cfthrow type="javaloader.InvalidInvocationException" message="Unable to determine what method to invoke" detail="Please check the documentation for switchThreadContextClassLoader."/>
153193
</cfif>

unittests/load/SwitchThreadContextTest.cfc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,66 @@
6767
</cfscript>
6868
</cffunction>
6969

70+
<cffunction name="testMixinApproachWithArguments" hint="testing using the mixing" access="public" returntype="void" output="false">
71+
<cfscript>
72+
var mixin = javaloader.switchThreadContextClassLoader;
73+
var args = { arg1 = 1, arg2 = 2};
74+
var result = mixin("returnCurrentClassLoaderAndArguments", args, javaloader.getURLClassLoader());
75+
assertSame(javaloader.getURLClassLoader(), result.classLoader);
76+
assertStructEquals(args, result.args);
77+
</cfscript>
78+
</cffunction>
79+
80+
<cffunction name="testPassUDFInWithArguments" hint="pass in a UDF with arguments" access="public" returntype="void" output="false">
81+
<cfscript>
82+
var args = { arg1 = 1, arg2 = 2};
83+
var result = javaloader.switchThreadContextClassLoader(returnCurrentClassLoaderAndArguments, args);
84+
assertSame(javaloader.getURLClassLoader(), result.classLoader);
85+
assertStructEquals(args, result.args);
86+
</cfscript>
87+
</cffunction>
88+
89+
<cffunction name="testPassUDFInWithArgumentsWithCustomClassLoader" hint="pass in a UDF with arguments" access="public" returntype="void" output="false">
90+
<cfscript>
91+
var urlClassLoader = createObject("java", "java.net.URLClassLoader").init(ArrayNew(1));
92+
var args = { arg1 = 1, arg2 = 2};
93+
var result = javaloader.switchThreadContextClassLoader(returnCurrentClassLoaderAndArguments, args, urlClassLoader);
94+
assertSame(urlClassLoader, result.classLoader);
95+
assertStructEquals(args, result.args);
96+
</cfscript>
97+
</cffunction>
98+
99+
<cffunction name="testPassObjectAndMethodNameWithArguments" hint="pass in the object and method name with arguments" access="public" returntype="void" output="false">
100+
<cfscript>
101+
var local = {};
102+
local.class = getMetadata(this).name;
103+
local.object = createObject("component", local.class);
104+
local.args = { arg1 = 1, arg2 = 2};
105+
106+
makePublic(local.object, "returnCurrentClassLoaderAndArguments");
107+
108+
local.result = javaloader.switchThreadContextClassLoader(local.object, "returnCurrentClassLoaderAndArguments", local.args);
109+
assertSame(javaloader.getURLClassLoader(), local.result.classLoader);
110+
assertStructEquals(local.args, local.result.args);
111+
</cfscript>
112+
</cffunction>
113+
114+
<cffunction name="testPassObjectAndMethodNameWithArgumentsWithCustomClassLoader" hint="pass in the object and method name with arguments, with a custom classloader" access="public" returntype="void" output="false">
115+
<cfscript>
116+
var local = {};
117+
local.class = getMetadata(this).name;
118+
local.object = createObject("component", local.class);
119+
local.urlClassLoader = createObject("java", "java.net.URLClassLoader").init(ArrayNew(1));
120+
local.args = { arg1 = 1, arg2 = 2};
121+
122+
makePublic(local.object, "returnCurrentClassLoaderAndArguments");
123+
124+
local.result = javaloader.switchThreadContextClassLoader(local.object, "returnCurrentClassLoaderAndArguments", local.args, local.urlClassLoader);
125+
assertSame(local.urlClassLoader, local.result.classLoader);
126+
assertStructEquals(local.args, local.result.args);
127+
</cfscript>
128+
</cffunction>
129+
70130
<!------------------------------------------- PACKAGE ------------------------------------------->
71131

72132
<!------------------------------------------- PRIVATE ------------------------------------------->
@@ -78,4 +138,12 @@
78138
</cfscript>
79139
</cffunction>
80140

141+
<cffunction name="returnCurrentClassLoaderAndArguments" hint="returns the current contexts classloader and any arguments passed in" access="private" returntype="any" output="false">
142+
<cfscript>
143+
var Thread = createObject("java", "java.lang.Thread");
144+
var result = { classLoader = Thread.currentThread().getContextClassLoader(), args = arguments };
145+
return result;
146+
</cfscript>
147+
</cffunction>
148+
81149
</cfcomponent>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#Default Properties
2-
#Tue Jan 31 18:41:16 EST 2012
2+
#Fri Mar 09 22:38:00 EST 2012
33
rootPath=/mnt/hgfs/wwwroot/javaloader/

0 commit comments

Comments
 (0)