Xpages runtime interpreting java package name as String object - xpages

From all the weirdness in our current Xpages project this one currently hits the ceiling:
we have created a few java beans in our current project. Inside Domino Designer they all are stored below Code >> Java, so that it is clear that they are automatically part of the project's classpath. All our beans belong to a package structure de.edcom.* (that's what we have been using forever without any problems). The objects are mostly called from SSJS using the full package names (the aren't registered as managed beans for various reasons) as in
var o = de.edcom.myObject.someMethod();
In none of my previous Xpages projects this caused any problems, it just worked. In the current project, however the XSP runtime all of a sudden started to interpret the package name as a String object giving us this runtime error:
Unknown member 'edcom' in Java class 'java.lang.String'
the ssjs code line in question is looking like this:
return de.edcom.TOC.buildTOC();
We absolutely don't have any clue as to what could be causing this, why only in this project, and why it sometimes IS working, but mostly isn't.
There's one difference between this projects and others before, and that is locallization: users can switch between "english" and "german" locale, and of course we are using codes like
context.setLocaleString("de")
and of course we are having several javascript code fragments looking for local settings as in
if(context.getLocalString()==="de"){...
This morning we in fact have renamed / refactored all java beans to different package names (com.edcom.*), and since then the error hasn't appeared (fingers crossed!).
But then again I think this is just too stupid, there can't really be a connection, or can it?
EDIT:
I tried using importPackage(), in conjunction with an xe:objectData datasource (as recommended by Adrian and Paul in their answers), but I'm still receiving that "unknown member 'edcom' in Java class 'java.lang,String'" message, now only at a different position in the code at my line saying importPackage(de.edcom).
I'll be switching back to the "com.edcom" package and keep looking for a better solution; unfortunately searching for the string "de" inside the entire code yields close to 12.000 matches; now way to find the real reason for this in that haystack
EDIT #2:
looks like we finally found the dreaded "de" variable: it was well hidden in a computed customControl property; I don't have a clue why all the File Searches that I performed over the last few days couldn't find this one.
Anyways it is very good to know that we have to be even more careful when naming our ssjs variables; I never would have thought that a ssjs variable name could ever interfere with TLD parts in Java packages; we probably will make it an internal policy that our variables have to must be named "vDe", "vCom", "vIt" etc. instead of just short lowercase letters...

Probably you used a variable de (which is a String) in an other SSJS script that run before that one faces the problem.
I've seen similar issues that a variable that is not explicitly declared in an script block can inherit values from another script block.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforeRenderResponse><![CDATA[#{javascript:
var ex1 = "Hello World";
var ex2 = "Bye bye"}]]>
</xp:this.beforeRenderResponse>
<xp:this.afterRenderResponse><![CDATA[#{javascript:
print("value ex1: " + ex1);
print("value ex2: " + ex2);}]]>
</xp:this.afterRenderResponse>
</xp:view>
results in:
[1CA8:000C-4354] 10.06.2016 14:33:01 HTTP JVM: value ex1: Hello World
[1CA8:000C-4354] 10.06.2016 14:33:01 HTTP JVM: value ex2: Bye bye
So you should use the importPackage() function to import the references to your java classes or much better, use managed beans or dataContexts.

SSJS requires variables which will be put in a scope. Anything with a dot in it will first go to those variables. It sounds like localization stores the translations in a variable named "de", that would explain your problem.
Maybe importPackage(de.edcom) and then using return TOC.buildTOC(); would resolve the problem. I would consider that better practice, but either way in SSJS you're risking variable name collisions.
Personally, I prefer to back every XPage with a controller Java class (I use Jesse Gallagher's frostillicus framework, and so it's always accessible with the variable pageController), so my SSJS just calls pageController.myMethod(), which then avoids all name collisions and allows Java imports to ensure I map to the right Java class. There are more basic ways of doing it, e.g. with an xe:dataObject at the top of every XPage.

Related

CFThread Arguments vs Attributes

For years, I've been using the following code across multiple ColdFusion environments:
<cfthread
action = "run"
name = "#Local.cachedFilename#"
src = "#Arguments.src#"
>
<!--- Process image --->
<cfset Local.objImage = This.processImage(
src = Arguments.src
) />
</cfthread>
I've come to reuse my component in a different environment today and for the first time I've hit an error, that Arguments.src does not exist inside the thread.
A bit of Googling returned an answer, I should be using the attributes scope inside a thread... so the ProcessImage call makes use of Attributes.src instead of Arguments.src.
This works fine. All is well. But I'm confused.
I wrote this code for Railo. It worked fine. I ported it over to CF10, it worked fine. I ran it on CF11. It worked fine.
The first time I've come across an error is on a particular box, also running CF10.
So my question is - was there an update somewhere, or is there some particular set of circumstances, that would allow me to use the arguments scope inside a CFThread? Essentially if I'm supposed to be using the attributes scope, how have I had this working fine for years?!
CFThread is a tag, not a function call. It therefore has attributes, not arguments. It would appear that Railo/Lucee for some reason incorrectly make the attributes available in an arguments scope as well. Adobe's behavior is correct IMO and you just got away with it by luck in the past on Railo.

Having problems decompiling class files

I have been working on a game for a while now and i tried to make this game as easy to understand as possible and easy to change as well by using one variable in a few places and not write the variables value in each place so that if i decide to change the value i wont have to change it every where, i will just have to change the value of the variable.
Two days ago i formatted my computer and saved in my external Hard Drive a .Jar file of the
game and the Eclipse(Coding environment) folder in where i THOUGHT the game source should be located at but it wasn't thus losing my source code.
I was very upset but then I remembered that you can decompile a jar file.
I searched for a decompiler and found the jd gui decompiler opened my jar file and i was happy
to see that its actually works but then... I noticed that the code is alliiiiitle bit different.
The compiler added tons of this. all the classes which doesn't matter to me.
Then i noticed that every where there was a double type number it added a .0 and a D
at the end of the number and even is some places where i had for example 0.7 i saw that there is 0.699999996 which again doesn't really matter, not a big deal.
But then i noticed that in all the places where i had a final variable it changed it to its value (Example : supposed to be : numRowsToDraw = Panel.WIDTH / tileHeight + 2;
what it is now : numRowsToDraw = 768 / tileHeight + 2;)
which ruined all the easy to change aspect of the program and i didn't want to change
the numbers back to the variable in all the places there should be a variable because it will take a lot of work.
So my question is : Is there a decompiler which doesn't change your code?
If there is can you tell me the name of it?
THANKS!
Oh and i forgot to mention that i tried afterwards the JAD decompiler which did the same thing...
No, there is not. Decompilation can never get back source level constructs like comments or the particular formatting of literals. But I'm sure there are automated source formatting tools out there that let you do stuff like remove Ds on double literals.

Is GroovyResourceLoader ever called outside the main ClassLoader?

Ive setup a GroovyResourceLoader and it seems to get requests for groovy scripts as necessary. I was just wondering is it specially used anywhere besides class loading ? Is there any benefit in simply wrapping a ClassLoader and loading *.groovy files there as opposed to using a GRL ? Are they just different ways to the same end ?
GroovyResourceLoader (GRL) is used by GroovyClassLoader (GCL) and at least since Groovy 1.8 indirectly through GroovyScriptEngine (GSE). But GSE loads it through a GCL as well.
But what GRL does is to "locate" the scripts and return an URL to the location. What GCL does is use the URL returned by a GRL to get the source and compile it to create the class, which is then available for loading.
GRL is a backend for GCL. So they are not different ways to the same end. True, you still have to do more things to actually execute the script code (unless it is precompiled), but "get the script source, compile it, make a Class out of it and finally execute it" are the steps you always have to do. In our GRL/GCL discussion, GRL does part of the first step, GCL itself does the third step. Step 2 is done by CompilationUnit inside GCL and the last step is yours to be done. There are other ways to complete these steps of course, but that's out of the scope for this discussion.

Overriding PromptService in newer XULRunner

Our application uses embedded xulrunner. We override the default PromptService to provide custom dialogs for alert, prompt, etc by
componentRegistrar.RegisterFactory (PROMPTSERVICE_CID, aClassName, aContractID, MyPromptServiceFactory);
where,
PROMPTSERVICE_CID is "a2112d6a-0e28-421f-b46a-25c0b308cbd0"
CONTRACT_ID is "#mozilla.org/embedcomp/prompt-service;1"
When using XULRunner 1.9.* versions, this works perfectly and the call comes to MyPromptSerivceFactory. But, this doesn't work on newer XULRunner versions (>= 4.0)
I have modified the PROMPTSERVICE_CID to "7ad1b327-6dfa-46ec-9234-f2a620ea7e00" (copied from nsPrompter.manifest). While registering the factory I get the error NS_ERROR_FACTORY_EXISTS.
If I continue to use the old PROMPTSERVICE_CID, then nsIPromptService2 is not used instead nsIWindowCreator2.CreateChromeWindow2 is used to display alerts and prompts.
I have googled on this, but I couldn't find a solution to either fix the NS_ERROR_FACTORY_EXISTS error or for MyPromptServiceFactory to be used.
Any help/suggestions?
It would probably be better to use the existing prompt service the way Firefox does it rather than replace it. If you look at nsPrompter.openPrompt(), before opening a modal dialog it will try to locate and call a JavaScript function getTabModalPrompt() in the window containing the browser. It expects to get a promptBox element back and will call methods appendPrompt() and removePrompt() on it. Obviously, you don't have to give it a promptBox element, just something that behaves similarly - and displays a message any way you like.
But if you really want to replace system components, you shouldn't duplicate prompter's CID - use your own one but #mozilla.org/prompter;1 as contract ID (the old contract ID is for backwards compatibility only).

Recompilation not working with groovlets

I'm new to groovy, really like it, but found a compilation problem. I'm using Jetty as a webserver, which is serving .groovy files (groovlets).
Consider two files:
Test1.groovy which contains
   
println new Test2().property
Test2.groovy which contains:
public class Test2 {
String property = "print this"
}
When calling /Test1.groovy in a browser it prints print this. But when I change the property in something else, it still prints print this, it won't recompile. The only thing I can do is restart jetty.
Note that when all the code is in one file, recompilation does work.
Is there a workaround for this?
I think the reason it's always displaying the default value is because you're newing it inline ... or is that just a problem with the example?
Thanks, but that's not it.
I am getting a little closer, the compiler can be fooled:
When calling /test2.groovy in a browser you get a server error, because test2.groovy only contains class code (and not a main method), but when you add the line
println "" to this file, it actually recompiles when calling it in a browser.
After that, test1.groovy should be recompiled too in order to make it work. It's not a very neat solution, but jetty doesn't need to be restarted this way...

Resources