XPages Standby control breaks Scrolling in Bootstrap - xpages

I have an XPages Bootstrap based application where some functions take a little time to process so I've added the OpenNTF Standby control (https://openntf.org/XSnippets.nsf/snippet.xsp?id=standby-dialog-custom-control) to the page to show an indicator during the Partial refresh.
Since dropping the control on the page after the partial refresh runs it seems to break the page's ability to scroll. I can scroll before the partial refresh but not after.
Anyone know how to fix this?

It sounds like you're getting a global JavaScript error (I'm curious as to the stack trace from your browser's console), which prevents further execution. While in development only (aka- don't force error handling like below), you could try adding a script early on to try and catch the culprit, you could try and load up a script, as early as possible, to force handling of the error to return true or, more importantly, dump out more information on what is throwing the error.
For more on the global error event handler, here's a link to the corresponding page on MDN.
function ignoreError(msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
if (string.indexOf(substring) > -1){
alert('Script Error: See Browser Console for Detail');
} else {
var message = [
'Message: ' + msg,
'URL: ' + url,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
alert(message);
}
return true; // normally, such a global exception ought to return false
}
window.onerror=ignoreError();

Related

chrome.tabs.executeScript is unreliable

I'm trying to inject content script dynamically so I'm using the documented chrome.tabs.executeScript method for this.
However, unlike embedded content scripts (defined in the manifest) the dynamic script runs on a random basis while I need to be sure it runs everytime.
Basically I listen for tab update events in background script and execute dynamic content script on every "loading" event
What I've noticed is that the behavior seems to be connected with page/script loading timing - if page loading completes before the script execution, the script won't run, otherwise it seems to work as expected.
Though this is just a guess based on the observation and if you have any other ides of what is going on here feel free to share your thoughts.
Is there any ways to ensure dynamic script executes 100% of the time despite of any circumstances?
Here is the log sequence in which script doesn't run:
loading: changeInfo = {status: "loading"}
loading: start. sender.tab.id = 1454
loading: start script loading
loading: code size = 4190306 bytes
loading: changeInfo = {status: "complete"} <- page loading completed
loading: time to execute script = 945 <- script execution completed
And here is the code snippet:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
console.log("loading: changeInfo = ", changeInfo)
if (changeInfo.status !== "loading") {
console.log("loading: skip");
return;
}
console.log("loading: start. sender.tab.id = ", tabId)
console.log("loading: start script loading")
var timerStart = Date.now();
console.log("loading: code size = ", byteCount(scriptCode), " bytes")
chrome.tabs.executeScript(tabId,
{
code: scriptCode,
runAt: "document_idle"
}, function (response) {
console.log("loading: time to execute script = ", Date.now() - timerStart)
var err = chrome.runtime.lastError;
console.log("loading: response = ", response, ", err = ", err)
});
});
There are also no errors in the log
One more thing to add - if I wrap chrome.tabs.executeScript in setTimeout with something like 2000ms delay this guarantees script will never run which suggests timing issue.
Ok, that was dumb - the problem appeared to be in the dynamic script code itself: the main logic was executed in the onload callback and was never run if the script loads after the onload:
window.addEventListener("load", mainLogic, false);
removing the callback and running mainLogic() directly fixed the issue.
I'll leave it here in case someone did the same mistake as I did.

IllegalStateException for getRequestDispatcher [duplicate]

This method throws
java.lang.IllegalStateException: Cannot forward after response has been committed
and I am unable to spot the problem. Any help?
int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
String chkboxVal = "";
// String FormatId=null;
Vector vRow = new Vector();
Vector vRow1 = new Vector();
String GroupId = "";
String GroupDesc = "";
for (int i = 0; i < noOfRows; i++) {
if ((request.getParameter("chk_select" + i)) == null) {
chkboxVal = "notticked";
} else {
chkboxVal = request.getParameter("chk_select" + i);
if (chkboxVal.equals("ticked")) {
fwdurl = "true";
Statement st1 = con.createStatement();
GroupId = request.getParameter("GroupId" + i);
GroupDesc = request.getParameter("GroupDesc" + i);
ResultSet rs1 = st1
.executeQuery("select FileId,Description from cs2k_Files "
+ " where FileId like 'M%' and co_code = "
+ ccode);
ResultSetMetaData rsm = rs1.getMetaData();
int cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol1 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol1.addElement(rs1.getObject(j));
}
vRow.addElement(vCol1);
}
rs1 = st1
.executeQuery("select FileId,NotAllowed from cs2kGroupSub "
+ " where FileId like 'M%' and GroupId = '"
+ GroupId + "'" + " and co_code = " + ccode);
rsm = rs1.getMetaData();
cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol2 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol2.addElement(rs1.getObject(j));
}
vRow1.addElement(vCol2);
}
// throw new Exception("test");
break;
}
}
}
if (fwdurl.equals("true")) {
// throw new Exception("test");
// response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
request.setAttribute("GroupId", GroupId);
request.setAttribute("GroupDesc", GroupDesc);
request.setAttribute("vRow", vRow);
request.setAttribute("vRow1", vRow1);
getServletConfig().getServletContext().getRequestDispatcher(
"/GroupCopiedUpdt.jsp").forward(request, response);
}
forward/sendRedirect/sendError do NOT exit the method!
A common misunderstanding among starters is that they think that the call of a forward(), sendRedirect(), or sendError() would magically exit and "jump" out of the method block, hereby ignoring the remnant of the code. For example:
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
This is thus actually not true. They do certainly not behave differently than any other Java methods (expect of System#exit() of course). When the someCondition in above example is true and you're thus calling forward() after sendRedirect() or sendError() on the same request/response, then the chance is big that you will get the exception:
java.lang.IllegalStateException: Cannot forward after response has been committed
If the if statement calls a forward() and you're afterwards calling sendRedirect() or sendError(), then below exception will be thrown:
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
To fix this, you need either to add a return; statement afterwards
protected void doXxx() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
... or to introduce an else block.
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
else {
forward();
}
}
To naildown the root cause in your code, just search for any line which calls a forward(), sendRedirect() or sendError() without exiting the method block or skipping the remnant of the code. This can be inside the same servlet before the particular code line, but also in any servlet or filter which was been called before the particular servlet.
In case of sendError(), if your sole purpose is to set the response status, use setStatus() instead.
Do not write any string before forward/sendRedirect/sendError
Another probable cause is that the servlet writes to the response while a forward() will be called, or has been called in the very same method.
protected void doXxx() {
out.write("<p>some html</p>");
// ...
forward(); // Fail!
}
The response buffer size defaults in most server to 2KB, so if you write more than 2KB to it, then it will be committed and forward() will fail the same way:
java.lang.IllegalStateException: Cannot forward after response has been committed
Solution is obvious, just don't write to the response in the servlet. That's the responsibility of the JSP. You just set a request attribute like so request.setAttribute("data", "some string") and then print it in JSP like so ${data}. See also our Servlets wiki page to learn how to use Servlets the right way.
Do not write any file before forward/sendRedirect/sendError
Another probable cause is that the servlet writes a file download to the response after which e.g. a forward() is called.
protected void doXxx() {
out.write(bytes);
// ...
forward(); // Fail!
}
This is technically not possible. You need to remove the forward() call. The enduser will stay on the currently opened page. If you actually intend to change the page after a file download, then you need to move the file download logic to page load of the target page. Basically: first create a temporary file on disk using the way mentioned in this answer How to save generated file temporarily in servlet based web application, then send a redirect with the file name/identifier as request param, and in the target page conditionally print based on the presence of that request param a <script>window.location='...';</script> which immediately downloads the temporary file via one of the ways mentioned in this answer Simplest way to serve static data from outside the application server in a Java web application.
Do not call forward/sendRedirect/sendError in JSP
Yet another probable cause is that the forward(), sendRedirect() or sendError() methods are invoked via Java code embedded in a JSP file in form of old fashioned way <% scriptlets %>, a practice which was officially discouraged since 2003. For example:
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<% sendRedirect(); %>
...
</body>
</html>
The problem here is that JSP internally immediately writes template text (i.e. HTML code) via out.write("<!DOCTYPE html> ... etc ...") as soon as it's encountered. This is thus essentially the same problem as explained in previous section.
Solution is obvious, just don't write Java code in a JSP file. That's the responsibility of a normal Java class such as a Servlet or a Filter. See also our Servlets wiki page to learn how to use Servlets the right way.
See also:
What exactly does "Response already committed" mean? How to handle exceptions then?
Unrelated to your concrete problem, your JDBC code is leaking resources. Fix that as well. For hints, see also How often should Connection, Statement and ResultSet be closed in JDBC?
even adding a return statement brings up this exception, for which only solution is this code:
if(!response.isCommitted())
// Place another redirection
Typically you see this error after you have already done a redirect and then try to output some more data to the output stream. In the cases where I have seen this in the past, it is often one of the filters that is trying to redirect the page, and then still forwards through to the servlet. I cannot see anything immediately wrong with the servlet, so you might want to try having a look at any filters that you have in place as well.
Edit: Some more help in diagnosing the problem…
The first step to diagnosing this problem is to ascertain exactly where the exception is being thrown. We are assuming that it is being thrown by the line
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
But you might find that it is being thrown later in the code, where you are trying to output to the output stream after you have tried to do the forward. If it is coming from the above line, then it means that somewhere before this line you have either:
output data to the output stream, or
done another redirect beforehand.
Good luck!
You should add return statement while you are forwarding or redirecting the flow.
Example:
if forwardind,
request.getRequestDispatcher("/abs.jsp").forward(request, response);
return;
if redirecting,
response.sendRedirect(roundTripURI);
return;
This is because your servlet is trying to access a request object which is no more exist..
A servlet's forward or include statement does not stop execution of method block. It continues to the end of method block or first return statement just like any other java method.
The best way to resolve this problem just set the page (where you suppose to forward the request) dynamically according your logic. That is:
protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
returnPage="page1.jsp";
}
if(condition2){
returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}
and do the forward only once at last line...
you can also fix this problem using return statement after each forward() or put each forward() in if...else block
I removed
super.service(req, res);
Then it worked fine for me
Bump...
I just had the same error. I noticed that I was invoking super.doPost(request, response); when overriding the doPost() method as well as explicitly invoking the superclass constructor
public ScheduleServlet() {
super();
// TODO Auto-generated constructor stub
}
As soon as I commented out the super.doPost(request, response); from within doPost() statement it worked perfectly...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//super.doPost(request, response);
// More code here...
}
Needless to say, I need to re-read on super() best practices :p
After return forward method you can simply do this:
return null;
It will break the current scope.
If you see this on a Spring based web application, make sure you have your method annotated with #ResponseBody or the controller annotated with #RestController instead of #Controller. It will also throw this exception if a method returns JSON, but has not been configured to have that as the response, Spring will instead look for a jsp page to render and throw this exception.

Performing Operations while Closing NodeJS

I have a Firebase Connection in nodejs that pushes data to a url while the connection is persistent, when it closes, I want to remove that data (think, I push "hey I'm here", and when I leave, the text disappears)
I made a "runnable" that shows an example of it:
http://web-f6176e84-c073-416f-93af-62a9a9fbfabd.runnable.com
basically, hit "ctrl + c" and it prints out "trying to remove reference" but never actually deletes the data ( the documents say that remove() is equivalent to set(null) which it basically sets the data to null, and since it's null, the entire element should be gone.)
However it's not removing it, I don't see the data ever "disappear". (I'm using a temp Firebase URL, you should be able to duplicate with any URL you can access if this url stops existing).
this is the code I'm using.
var FB_URL = 'https://cuhiqgro1t3.firebaseio-demo.com/test_code';
var Firebase = require('firebase');
var myRootRef = new Firebase(FB_URL);
console.log("created Firebase URL");
process.stdin.resume(); //so the program will not close instantly
function delete_fb_entries() {
return function() {
console.log("Trying to remove reference");
myRootRef.remove();
process.exit();
}
}
//do something when app is closing
process.on('exit', delete_fb_entries());
//catches ctrl+c event
process.on('SIGINT', delete_fb_entries());
//catches uncaught exceptions
process.on('uncaughtException', delete_fb_entries());
EDIT: Additional Information as to the "why", I push my local IP address out to my Firebase URL cause I'm lazy and it's easier to just have a webpage setup I can always access that will show the url of particular devices (and I know using the routers tables would be easier), I actually also have other purposes for this usage as well (if I happen to be inside my network, I can just select a particular device from my webpage and access the data I need, either way, it works, but I just can't get it to remove itself correctly, this used to work at one point in time I believe, so I can only assume the API has changed or something).
EDIT 2: OK removed process.exit() as suggested, and the runnable seemed to delete the data in question, I tried it on my local data (and after some cleaning up and commenting out), it removed the data, however when I hit Ctrl + C it no longer exits the program.....so yay.
I need to figure out if "process.exit()" is necessary or unnecessary at this point.
Edit 3: Ok so I need to use process.exit (as far as I can tell, Ctrl + C no longer exits the program, I have to ctrl + Z, and reboot). I tried adding it right after, but I realized that removing a firebase element is not a synchronus operation, so when I close it I tried (the next attempt) was to use the on complete handler for the remove function (so remove(onComplete), and then adding the process.exit() to the onComplete function).
So finally it looks like this and it seems to be working with my application
var FB_URL = 'https://cuhiqgro1t3.firebaseio-demo.com/test_code';
var Firebase = require('firebase');
var myRootRef = new Firebase(FB_URL);
console.log("created Firebase URL");
function onComplete() {
process.exit();
]
process.stdin.resume(); //so the program will not close instantly
function delete_fb_entries() {
return function() {
console.log("Trying to remove reference");
myRootRef.remove(onComplete);
}
}
//do something when app is closing
process.on('exit', delete_fb_entries());
//catches ctrl+c event
process.on('SIGINT', delete_fb_entries());
//catches uncaught exceptions
process.on('uncaughtException', delete_fb_entries());
EDIT 4: In response to comments below, So I tried modifying a simple program to be the following:
function delete_fb_entries (){
return function () {
console.log("I should quit soon");
}
}
process.stdin.resume(); //so the program will not close instantly
//catches ctrl+c event
process.on('SIGINT', delete_fb_entries());
My program never exited. I don't understand why node would not close in this case, changing to add a process.exit() after the console.log causes nodejs to quit. This is not an async function, so why is it not exiting in this case? (Is this a bug, or a misunderstanding of how this works by me?)
You cannot perform asynchronous operations in a process's exit event handler, only synchronous operations, since the process is exited once all exit event handlers have been executed.

adding custom font in my app

while adding custom font in my app, it's crashing some time.
But most of the time it get executed smoothly.
i'm using following code.
try {
// Get the typeface
ShravyaApp.appTypeFace = Typeface.createFromAsset(getApplication().getAssets(),
"kadage.ttf");
Log.d("font","in type="+ShravyaApp.fontName);
Log.d("font","type face="+ShravyaApp.appTypeFace);
}
catch (Exception e)
{
ShravyaApp.appTypeFace = Typeface.createFromAsset(getApplication().getAssets(),
"kadage.ttf");
Log.d("font","in catch typr="+ShravyaApp.fontName);
Log.d("font","type face="+ShravyaApp.appTypeFace);
//Log.e(TAG, "Could not get typeface '" + + "' because " + e.getMessage());
e.printStackTrace();
}
The Error i'm getting is :
NullPointerException
at android.graphics.Typeface.nativeCreateFromAsset(Native Method)
at android.graphics.Typeface.createFromAsset(Typeface.java:280)
This could be IO Exceptions in the nativeCreateFromAsset. Also this can be because you are calling this method before Activity onCreate().
Any way try using retry mechanism with 100 milliseconds sleeping between retries, there is no reason that it will not work, unless some bug in the user device.
Why place the same code in both try and catch?
I suggest you use a Typface-cache (example here) and if your app really requires the font, you may want to refactor your method into a recursive one and as Babibu said, pause in between.
I am guessing getApplication() is the function that returns a null pointer. It needs to be called in the onCreate(), not in the constructor. We need more context to be sure.
Also you can set a breakpoint catching null pointer exceptions in the debug mode.

How to do Basic Authentication using FireWatir on Ubuntu Linux?

I'm trying to use FireWatir (1.6.5) to access a site using Basic
Authentication and I've been unable to find a solution that works on
Firefox in Linux. Does FireWatir 1.6.5 support Basic Authentication
on Linux? I've been searching the web for 2 days and can't get a
straight answer anywhere as to how to do this.
The only thread I found that seemed helpful was this one (
http://groups.google.com/group/watir-general/browse_thread/thread/d8ab9a177d282ce4/fc1bf2319fb387d8?lnk=gst&q=basic+authentication#fc1bf2319fb387d8).
Aedorn Varanis says " Angrez's fork had the solution so I'm using that
now. Thanks Angrez, works perfectly!", but he doesn't mention what he
did to get things working.
Initially I tried to bypass the authentication dialog box by using:
browser.goto('http://admin:password#172.20.1.1')
However, this generates a "Confirm" dialog which says:
"You are about to log in to the site "172.20.1.1" with the username
"admin"." [Cancel, OK]
This dialog blocks, and the goto call won't return until I click "OK".
Then I tried adding:
browser.startClicker("ok")
browser.goto('http://admin:password#172.20.1.1')
But this ALSO generates the same "Confirm" dialog.
I tested out the startClicker functionality using the unit test /var/
lib/gems/1.8/gems/firewatir-1.6.5/unittests/html/JavascriptClick.html
and it worked fine, which makes me think that using the startClicker
method is NOT the correct way to take care of the Confirm dialog.
Anybody else found a way to get Basic Auth to work, or how to click
the OK on the confirm dialog? I'm at my wits end...
This may be a long ugly workaround, and may also violate the simplicity of watir's philosophy, but since you are at your wits end ...
1) Sahi (http://sahi.co.in/) handles 401 authentication dialogs by converting them into regular web pages.
2) Sahi's proxy needs to be running, and you point your browser to use Sahi's proxy.
3) You can then navigate to your page and just use watir/firewatir to enter username password into a converted 401 authentication web page, (like a regular form).
You would incur the extra load of the proxy, but Sahi is fairly well behaved so you should be able to make it work.
You could post here or on Sahi's forums if you need further assistance.
Hope that helps.
-Narayan
With help from Aedorn Varanis I've got things working on Firefox in
Linux.
Aedorn sent me a "logon" method which issues a jssh command that
checks for an "Authentication Required" dialog and if it exists, fills
in the username/password and submits the dialog.
I've copied and pasted what he sent me below:
You use a method that looks like this:
def logon(username, password, wait=3)
jssh_command = "var length = getWindows().length; var win;var found=false; for(var i = 0; i < length; i++) { win = getWindows()[i]; if(win.document.title == \"Authentication Required\") { found = true; break; }} if(found) { var jsdocument = win.document; var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";"
jssh_command << " dialog.getButton(\"accept\").click(); }\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
wait()
end
Then you can call it within its own
thread just before going to the site
with the login requirement:
Thread.new { logon(user, pass) }
#ff.goto("http://some_url.com")
sleep 3
Increase the wait and sleep time if
the page takes awhile to load. If your
main process tries to run while the
command is being sent through the JSSH
socket, it will stall and sit there
forever until killed. Also, there's no
real way to detect if the
authentication window comes up. That
means you need to make sure it always
works the same way every time, or it,
too, causes problems. Finally, the
method will always have to be in
another thread, because once the
authentication window comes up, it
stops all other processing until it
goes away. Other than that, it works.
From this, I was able to subclass the FireWatir::Firefox class with a
new Browser class which supports a "credentials=" method just like the
Celerity::Browser does. So, just like using celerity, you can do:
require 'browser'
browser = Browser.new
browser.credentials = 'user:pass'
browser.goto('http://some.basic.auth.url')
This will automatically fill in the Basic Auth dialog and log you into
the site.
I've posted the contents of my browser.rb file below (notice this
works in ruby+firewatir and jruby+celerity in linux):
ENGINE = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
if ENGINE == 'ruby'
require 'firewatir'
class Browser < FireWatir::Firefox
def initialize(options={})
super(options)
#username = nil
#password = nil
end
def credentials=(string)
username, password = string.split(":")
if username.nil? or password.nil?
raise "Invalid credentials: #{string})"
else
#username = username
#password = password
end
end
def goto(url, wait=3)
if #username.nil? and #password.nil?
return super(url)
else
t = Thread.new { logon(#username, #password, wait) }
result = super(url)
t.join
return result
end
end
private
def logon(username, password, wait)
jssh_command = "
var length = getWindows().length;
var win;
var found = false;
for (var i = 0; i < length; i++) {
win = getWindows()[i];
if(win.document.title == \"Authentication Required\") {
found = true;
break;
}
}
if (found) {
var jsdocument = win.document;
var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];
jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";
jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";
dialog.getButton(\"accept\").click();
}
\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
end
end
elsif ENGINE == 'jruby'
require 'celerity'
class Browser < Celerity::Browser; end
else
raise "Ruby ENGINE '#{ENGINE}' not supported."
end
I battled long and hard with this issue until today. Apparently i overlooked the answer many times because it didn't look plausible. However, the solution lies in Firefox's "network.http.phishy-userpass-length" profile configuration. If FireWatir allows you to modify your firefox instance Profile, then you can give the "network.http.phishy-userpass-length" a value of 255 which should make that dialog disappear. check http://kb.mozillazine.org/Network.http.phishy-userpass-length for more details.
Note: With Capybara + selenium-webdriver in Ruby, I did;
require 'capybara'
require 'selenium-webdriver'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['network.http.phishy-userpass-length'] = 255
Capybara::Selenium::Driver.new(:profile => profile, :browser => :firefox)

Resources