Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Let us verify. What does this tell you:
<cfoutput>#HelloWorldApp.getClass().getName()#</cfoutput>
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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"));
Copy link to clipboard
Copied
I've just given it a try but, unfourtunately adding init() had no effect. It still returns false. Will be happy to try other things if you have some to suggest.
Copy link to clipboard
Copied
I was wondering whether it had something to do with the package. Is example a package name?
Copy link to clipboard
Copied
This is how it is defined in my HelloWorld.scala
package example
class HelloWorld {
..
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
I've tried just "HelloWorld" but that doesn't work either. If you have any suggestiongs on how I can try instanceOf I will do it.
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
The .jar with the class in question is in the same directory as the script and I am using CF10's functionality to dynamically load jars from arbitrary paths. Probably I should have mentioned it earlier.
Copy link to clipboard
Copied
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"))#</cfoutput>
</p>
Copy link to clipboard
Copied
1st test: Case sensitivity
NO
2nd test: cfobject
NO
Copy link to clipboard
Copied
For want of a better idea, jot down the absolute path of the directory that contains /example/HelloWorld.class. Add that path to your loadPaths attribute. Incidentally, how do your dynamic settings this.javaSettings look like?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Thorough! Thanks.
The test I last suggested is therefore:
this.javaSettings.loadPaths = ['.\', '.\jars\','.\jars\cfjavatest.jar'];
That should cover them all.
Copy link to clipboard
Copied
Unfortunately the result is the same. It still gives false result. If you have other suggestions, I will be happy to try them. You know, Scala is the next Java, so I think this will be useful.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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).
Copy link to clipboard
Copied
Kirill_Grishin wrote:
That gave a YES
That's the gateway test, yes?
Copy link to clipboard
Copied
Yes, the test for "examples.JMS.JMSGateway" gave a YES.
Trying to cal index.cfm from the same directory where the jar is located gave NO though.
Copy link to clipboard
Copied
Kirill_Grishin wrote:
Yes, the test for "examples.JMS.JMSGateway" gave a YES.
That's a relief. So there is still hope.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Sorry for late reply!
Moving the .jar file to the same directory where index.cfm and Application.cfc are located did not have any effect.
Copy link to clipboard
Copied
Could you send me the JAR file? I have mailed you my e-mail address.