Hi.
I've created a simple class in Scala and packed it into a .jar file. I have no problems loading it into ColdFusion and running its methods.
Here is a copy of cfdump of the created object:
| object of example.HelloWorld | ||
| Class Name | example.HelloWorld | |
| Methods | Method | Return Type |
| Country() | example.HelloWorld$Country$ | |
| cn() | example.HelloWorld$Country | |
| countriesList() | scala.collection.immutable.List | |
| countriesMap() | scala.collection.immutable.Map | |
| getCountryByCode(java.lang.String) | scala.Option | |
| ja() | example.HelloWorld$Country | |
| ru() | example.HelloWorld$Country | |
| us() | example.HelloWorld$Country | |
But I have problems with isInstanceOf function with this object. If I run:
HelloWorldApp = CreateObject("java","example.HelloWorld");
writeOutput(isInstanceOf(HelloWorldApp,"example.HelloWorld"));
I get false as a result, but it should be true, right? The class does get loaded properly by CreateObject function.
Is there a workaround? The cfdump tag somehow manages to get the proper type of the object which it displays in the Class Name field of the dump table.
Thank you.
I am sorry for late response. The result of that code is "example.HelloWorld", so yes, it does return the correct name of Scala type. I also tried this approach for scala.Option type and it seems to be working.
Though, for example, the return type of getCountryByCode(java.lang.String) function is defined as scala.Option, the actual result's type is either scala.Some ot scala.None$ (which of cause are subtypes of scala.Option), which makes it possible to distinguish if the result of the computation was a fail or not.
Thank you for your help. It seems like I will have to use this approach for checking types.
I am surprised that isInstanceOf misses the HelloWorldApp instance of "example.HelloWorld". That seems buggy to me. Does it do better with the default constructor? That is
HelloWorldApp = CreateObject("java","example.HelloWorld").init();
writeOutput(isInstanceOf(HelloWorldApp,"example.HelloWorld"));
I wondered whether isInstanceOf expects just the class name, HelloWorld, and not the fully qualified name, example.HelloWorld. Will this work:
HelloWorldApp = CreateObject("java","example.HelloWorld");
writeOutput(isInstanceOf(HelloWorldApp,"HelloWorld"));
I have been looking for clues on how isInstanceOf handles types defined with package names. I found very little in ColdFusion's documentation. So, I am looking into Java's documentation on instanceOf.
I have not been looking for a way to do it with Java's instanceof operator. That would be running away. I have been looking at how instanceof is used with fully qualified names, hoping to learn something from there.
However, I have only been able to confirm that your original code is correct, and should work! I am wondering whether it fails in your case because of the classpath.
What is the absolute path of the directory that contains 'example.HelloWorld'? Go to the ColdFusion administrator. Click on the
button for information. Is the directory in the classpath?
OK. Moving on, two tests:
<p>
1st test: Case sensitivity<br>
<cfscript>
helloworldapp = createObject("java","example.HelloWorld");
writeOutput(isInstanceOf(helloworldapp,"example.HelloWorld"));
</cfscript>
</p>
<p>
2nd test: cfobject<br>
<cfobject action="create" name="helloworldapp" type="java" class="example.HelloWorld">
<cfoutput>#isInstanceOf(helloworldapp,"example.HelloWorld"))#</cfoutpu t>
</p>
Hi.
Application.cfc
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\Application.cfc
...
this.javaSettings.loadPaths = [ExpandPath('./jars')];
this.javaSettings.loadColdFusionClassPath = false;
this.javaSettings.reloadOnChange = true;
...
index.cfm
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\index.cfm
The Jar file
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\jars\cfjavatest.jar
jar's contents:
example\
HelloWorld.class
..
META-INF\
..
scala\
..
library.properties
If you wish, I can upload the jar somewhere. It is about 8M because it contains the entire Scala library though.
No! What's going on?
Ok, let's now test one which we know is a yes.
myGateway = CreateObject("java","examples.JMS.JMSGateway");
writeOutput(isInstanceOf(myGateway,"examples.JMS.JMSGateway"));
If that gives a Yes, then the next test I would perform is a server restart(if that is possible). If it gives a No, then we know what we have in our hands.
Hang on a minute! I have this niggling feeling ColdFusion's isInstanceOf might be expecting the qualified name jars.example.HelloWorld.
Just for giggles, run the original index.cfm page one directory up, in the jars directory. That is, make a copy to
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\jars\index.cfm
and run it.
That gave a YES (though to load this class I needed to comment out javaSettings in the Application.cfc because I had loadColdFusionClassPath set to false, and restart the server after that because changes to javaSettings in Application do not take effect unless I restart the server). So, as you know by now, I've restrted the server multiple times (local machine, Windows 7 32, ACF10 with the latest, 6th, update).
An alternative test to the index.cfm relocation is to test by relocating cfjavatest.jar. Leave index.cfm in its original location. Return your Application.cfc to its original state. Then modify it as follows:
this.javaSettings.loadPaths = ['.\', '.\cfjavatest.jar'];
Move the file cfjavatest.jar one directory down to:
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\cfjavatest.jar
If you're up for it, I just thought of another test. At least for the time being. I am assuming the JAR file is at the original location,
C:\ColdFusion10\cfusion\wwwroot\org\cfjava\jars\cfjavatest.jar
In Application.cfc, comment out all the lines involving this.javaSettings. Go to the Java and JVM page in the Administrator. Add the following to the classpath:
C:/ColdFusion10/cfusion/wwwroot/org/cfjava/jars/;C:/ColdFusion10/cfusi on/wwwroot/org/cfjava/jars/cfjavatest.jar
Press the button to submit the changes. To be sure, restart ColdFusion.
Any joy?
Thanks for the JAR file. Here follows my progress report.
As a first test, I commented out the code this.javasettings=.... I unpacked the JAR file and copied its contents (example and scala directories) to C:\ColdFusion10\cfusion\wwwroot\WEB-INF\classes\. I restarted ColdFusion. When I run your original isInstanceOf code, I get a Yes.
I have been able to reproduce the issue (failure of isInstanceOf with dynamic Java settings) time after time. I am beginning to wonder whether you have uncovered a bug. However, I did find another positive result.
Comment out the code this.javasettings=.... Move the file cfjavatest.jar to the directory,
C:\ColdFusion10\cfusion\wwwroot\WEB-INF\lib\
Restart ColdFusion. When you run the original isInstanceOf code, you get a Yes.
@Kirill_Grishin
I decided to round this up before the end of the year. I am sorry I haven't been able to do better than find the above workarounds.
IsInstanceOf(helloworldapp,"example.HelloWorld")) continues to return No for dynamic Java settings. I have reproduced the behaviour using every conceivable directory structure in the loadPaths attribute in this.javaSettings. As far as I can see, what you have discovered is a bug.
Please consider filing a bug report. In fact, someone reported a similar bug (3121307) as far back as February 2012, when ColdFusion 10 was still in pre-release beta. Apparently that problem remains unsolved!
North America
Europe, Middle East and Africa
Asia Pacific