Java error in FireFox - myApplet.myFunction is not a function - java

I am getting an error that is only reproducible in Firefox.
In IE, it always works.
I have an ASP.NET application that targets an applet. For most functionality, it works great, but when I run one function (a function that does a lot of different things), the methods on the java applet seems to be unavailable! When I call any functions on the java applet from Javascript code, I get the error : myApplet.myFunction is not a function .
After this has happened, I get the same error for everything that calls functions on the applet, also functionality that worked prior to this state.
The applet is not unloaded or crashed, which is proved by that the interactive functions in the applet still works. But if the applet calls a javascript function on the page that calls back to the applet, I get the same error!
Sometimes it works when I repeat the action several times.
This only happens on the public version of the web application. Not in my local web app that runs on development machine. The main difference is that the public one use login access.
Can anyone give me hint of what can be causing this?
To summairize whats happens: When I run a particular bit of javascript code, the API against the java applet becomes unabailable (Error: myApplet.myFunction is not a function).
Here is the function that causes this buggy state of the applet:
function ParseAndZoomToAddress (objString) {
var mapFrame
eval("var objArray = new Array(" + objString + ")")
if (objArray.length > 0) {
mapFrame = window.frames[0].frames['mapFrame']
if(!mapFrame) alert('mapFrame is null!')
else window.status = 'mapFrame is OK!'
var center_x = 0
var center_y = 0
if(objArray.length == 1) {
var rExp1 = /[G-P]/g
var rExp2 = /[Q-Z]/g
eval("var coordArray = new Array(" + objArray[0].replace(rExp1, '0x').replace(rExp2, ',0x') + ")")
if(coordArray.length == 2){
center_x = coordArray[0]
center_y = coordArray[1]
}else{
alert("Invalid ID " + objArray[0])
}
}else{
var center_x = objArray[1]
var center_y = objArray[2]
}
var objZoomScale = '2000' // document.SearchForm.Scale.value
var scale = mapFrame.m_yur - mapFrame.m_yll
if (objZoomScale != "") {
scale = ScaleToMeter(parseInt(objZoomScale),mapFrame.m_image_width)
}
var xll = center_x - (scale / 2.0)
var yll = center_y - 10
var xur = xll + scale
var yur = center_y + 10
center_x = (xll + xur) / 2.0
center_y = (yll + yur) / 2.0
center_x = Math.round(center_x * 1000) / 1000
center_y = Math.round(center_y * 1000) / 1000
mapFrame.ResetClipPolygon() //This calls applet methods
var lCenterSymbol = '5024,40,85,x,y,5'
var rExp = /x/gi
lCenterSymbol = lCenterSymbol.replace(rExp,center_x)
rExp = /y/gi
lCenterSymbol = lCenterSymbol.replace(rExp,center_y)
mapFrame.parent.m_CenterSymbolString = lCenterSymbol
mapFrame.ResetClipPolygon() //This calls applet methods
mapFrame.previewVisible()
mapFrame.mapVisible()
mapFrame.setMove(false) //This calls applet methods
mapFrame.ZoomToArea(xll, yll, xur, yur) //This calls applet methods
mapFrame.parent.m_CenterSymbolString = ""
}
}
Additionaly I can say that the applet is defined by the <applet> tag.
The applet is located inside a <div> tag that is hidden in javascript with style.display='none' and shown again with style.display='block'.
This is done during the 2 lines:
mapFrame.previewVisible()
mapFrame.mapVisible()
I don't know if this is the problem, but these function are called elsewhere as well where it doesn't cause this, but it might be combination of things.
I am happy to get hint's that will help me solve this, not an absolute solution.
I will accept the best hint as the answer.

Perhaps this is a timing issue. It could happen that the Firefox engine tries to execute the javascript code before the java applet has been properly loaded. To verify this add a delay before accessing the applet in javascript code. Even better use a try-catch block for your call and wrap it in a for-loop. If the call is successful exit the loop, otherwise add a delay and retry.
Edit: Based on your edits it seems that there isn't a timing issue. Since your javascript function is quite big, I would try to locate, where the problem first appears. Create a dummy applet method and call it inside your javascript method at various places. Find out after which statement the problem first appears. Also, if you haven't done that already, install Firebug and watch out for javascript errors.

I was suddenly able to reproduce it in my development environment, so it was easier to locate the problem. The problem was related to hiding/showing as I suspected, but I'm still not sure why it was a problem. It was probably some sort of timing issues as noted by kgiannakakis, so will credit him with the bounty reward.
The problem disappeared when commenting out these two lines:
mapFrame.previewVisible(); // appletDiv.style.display="none"
mapFrame.mapVisible(); // appletDiv.style.display="block"
The comment at end is basically what is done inside those functions with the div that contains the applet.
So far, so good.
The intention with the Visible functions are originally switching 2 tabs where one of them displays the applet (mapVisible), and the other displays a static image (previewVisible). If I click the preview tab, that basically runs previewVisible(), the appletDiv is hidden. If I then run my big nasty function (ParseAndZoomToAddress) then I get the error again, but this time it is somewhat expected, since the applet is hidden (and obviously FireFox does not like to work with hidden applets..).
Then I remember why I included these calls inside the ParseAndZoomToAddress function: I have to make sure the applet is visible before accessing it! So I try to re-introduce the call to mapFrame.mapVisible(), and guess what - it works! Even if the applet was hidden, it is available after the call to mapFrame.mapVisible().
Anyone have a conclusion to this?
My theory is that it causes problems to unload and reload the applet so close together in the same javascript function.

I came here through a search, as I had exactly the same problem in Firefox (not MSIE), on web pages that I knew I had not changed for years and that I knew had worked fine before in Firefox.
myApplet.myFunction is not a function
As it turns out, in my case the culprit is just having the Google Translate Tools Javascript code described at
http://translate.google.com/translate_tools?hl=en&layout=1&eotf=1&sl=bg&tl=en
After I had removed that snippet from my included Javascript file (included at the bottom of my applet page), myApplet.myFunction worked fine again!
It also fixed the mysterious problem that my applet would not always load when loading the web page. Maybe Google Translate Tools under the hood also fiddles with style.display or similar, but I did not further dig into that.
I suspect that many others who use Google Translate Tools on a Java applet page with Javascript controls are similarly affected.

This post seems to have similar problem. They claim they fixed some HTML syntactic error and then it worked in Firefox.

I had a similar problem.
We fixed it by putting the <applet></applet> inside a <div> that has no display:none style.
JavaScript in Firefox cannot see functions in an applet that is inside a div that is not displayed.

Related

Struts 1 - Calling more actions via one post without altering struts-config

I'm working on a legacy app (struts 1, own framework, java 6, on WebSphere 7) where I need to change the behavior of an operation.
Let's call them (1) CopyItem, (2) AlterItem, (3) MarkAsCopied.
A button called one service which needs to be replaced with three other services.
Depending on the result of the first one, invoke the second one and so on.
I want to navigate in the end where the first one would take me (so it would look like the original behavior from user point of view).
Initially I thought I wrap every parameter I need into a form, POST it, and then on the Java side, I would call action execute for each service. Technically from CopyItemAction.execute() of CopyItem I would call AlterItem and MarkAsCopied executes as well.
I feel that this is pretty far from a clean solution.
Do you have a better idea, how to do this?
In the end I did it via synchronized Ajax. Which is definitely bad practice, so I do not recommend if you have the access on the backend code. However in my case now it turned out to be a working not-that-ugly solution. Based on Dave Newton's (https://stackoverflow.com/users/438992/dave-newton) proposal.
Keep that in mind the struts actions are still called according to the configuration defined in struts-config.xml.
I created the js function below and invoked the services with the specified forms one by one. This way a form (POST) submit calls the struts action, but doesn't navigate away. After they run successfully I redirected the page.
function submitForm(form) {
if (form !== null && form !== undefined) {
let formData = new FormData(form);
let xhr = new XMLHttpRequest();
xhr.open('POST', form.getAttribute('action'), false);
var successResponse = false;
xhr.onreadystatechange = function() {
if(xhr.readyState == XMLHttpRequest.DONE) {
successResponse = xhr.status == 200;
}
}
xhr.send(formData);
return successResponse;
}
}
In conclusion: this is not a recommended solution, but if you're in such a situation like me, then it works.

Matlab drag and drop file from windows explorer to figure (gui)

I would like to know it there is a way to drag a file from Windows explorer and drop it in my GUI.
The goal should be to get the file path (or folder path) and be able to load it with my own loading function.
I precise that I am using Matlab 2015b in Windows 10 64bits.
I edit my post to give an code example of what I am trying to do (based on Yair Altman solution and other found in Internet) :
function demo
% Set-up a figure droppable axis
hFig = figure('name','DND example','numbertitle','off');
hAx1 = axes('position',[.1,.1,.8,.8]);
% Enable drop on the figure axis
dnd = handle(java.awt.dnd.DropTarget(),'callbackProperties');
jFrame = get(hFig,'JavaFrame');
jAxis = jFrame.getAxisComponent;
jAxis.setDropTarget(dnd);
set(dnd,'DropCallback',{#dndCallbackFcn,hFig, hAx1});
set(dnd,'DragOverCallback',#dndCallbackFcn);
end
function dndCallbackFcn(varargin)
persistent transferable
eventData = varargin{2};
if eventData.isa('java.awt.dnd.DropTargetDropEvent') %nargin>2
hFig = varargin{3}; % my figure is passed as the third argument
try
eventData.acceptDrop(eventData.getDropAction);
transferable = eventData.getTransferable;
catch
end
dataFlavorList = java.awt.datatransfer.DataFlavor.javaFileListFlavor;
fileList = transferable.getTransferData(dataFlavorList);
%{
I want here to get back the file path and then call my loading function
%}
end
end
I always get an error in the line :
fileList = transferable.getTransferData(dataFlavorList);
The error is the following :
Java exception occurred:
java.awt.dnd.InvalidDnDOperationException: No drop current
at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(Unknown Source)
at sun.awt.datatransfer.TransferableProxy.getTransferData(Unknown Source)
at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(Unknown Source)
I tried to implement same functionality as yours and fall into the same exceptions when trying to get transferable data.
It is rather unclear if getTransferable fails because of default FlavorMap instantiated in %matlabroot%\sys\java\jre\...\lib\flavormap.properties (as pointed in Yair Altman's book
in drag and drop section) or for some other strange reason. Anyway I came accross this dndcontrol object on file exchange which works like a charm for our purpose by managing transferable data on java side directly.
I get inspired from this to wrote my own matlab proxy on top of java.awt.dnd.DropTarget that is more generic and closer to its java implementation peer (i.e. it works exactly the same way as java DropTarget object except that all data types have been converted to more standard and convenient matlab types).
You can download my implementation from here:
GitHub: DropListener
FileExchange: DropListener
And here is some usage example for doing what you need (drop in matlab axis from file explorer):
%
% PURPOSE:
%
% Show how to add drop support from file explorer to some matlab axis
%
% SYNTAX:
%
% [] = DropListenerDemo();
%
% USAGE:
%
% Simply drop files from file explorer into displayed axis.
%
%%
function [] = DropListenerDemo()
%[
% Create a figure with some axis inside
fig = figure(666); clf;
axes('Parent', fig);
% Get back the java component associated to the axis
% NB1: See §3.7.2 of Undocumented Secrets of Matlab Java Programming
% NB2: or use findjobj, or javaObjectEDT for drop support onto other component types
jFrame = get(handle(fig), 'JavaFrame');
jAxis = jFrame.getAxisComponent();
% Add listener for drop operations
DropListener(jAxis, ... % The component to be observed
'DropFcn', #(s, e)onDrop(fig, s, e)); % Function to call on drop operation
%]
end
function [] = onDrop(fig, listener, evtArg) %#ok<INUSL>
%[
% Get back the dropped data
data = evtArg.GetTransferableData();
% Is it transferable as a list of files
if (data.IsTransferableAsFileList)
% Do whatever you need with this list of files
msg = sprintf('%s\n', data.TransferAsFileList{:});
msg = sprintf('Do whatever you need with:\n\n%s', msg);
uiwait(msgbox(msg));
% Indicate to the source that drop has completed
evtArg.DropComplete(true);
elseif (data.IsTransferableAsString)
% Not interested
evtArg.DropComplete(false);
else
% Not interested
evtArg.DropComplete(false);
end
%]
end
The object also support for catching DragEnter, DragOver, DropActionChanged, DragExit event so you can tune every aspects of dragging operation. With little effort, it can also be extended to support for image dragging or other data types dragging.
Hope you'll like it and you'll find it generic enough to think of other usages.
There is a post at Matlab Central which uses a compiled java class. A stackoverflow answer included the code. With that solution, your demo may look like this:
function demo
% Set-up a figure droppable axis
hFig = figure('name','DND example','numbertitle','off');
warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
jFrame = get(hFig,'JavaFrame');
jAxis = jFrame.getAxisComponent;
% dnccontrol class from above link
dndcontrol.initJava();
dndcontrol(jAxis, #dropCallbackFcn);
end
function dropCallbackFcn(~, evt)
fileparts(evt.Data{1}) % show dropped file's path
end

Ruby on Rails, How to Update Div with Ajax on like/unlike

So the problem I am having is getting my like/unlike button to refresh with ajax in my Ruby on Rails app, here is my code:
app/views/_comment.html.haml
- likes = comment.likes
%div.comment{id: "comment-#{comment.id}"}
.comment-avatar
.medium-user-avatar.avatar-canvas
- if comment.user.avatar_url
= image_tag comment.user.avatar_url(:medium)
- else
%span.medium-user-initials.initials-decoration
= comment.user.avatar_initials
%span.comment-username= link_to(comment.user_name, "#")
%span.comment-body~ markdown(comment.body)
.comment-time
= time_ago_in_words(comment.created_at) + " ago"
- if can? :like, comment
= " · "
- if likes.find_by_user_id(current_user.id).nil?
= link_to "Like", like_comment_path(comment), method: :post, remote: true
- else
= link_to "Unlike", unlike_comment_path(comment), method: :post, remote: true
- if comment.user == current_user
= " · "
= link_to "Delete", comment_path(comment), method: :delete, remote: true,
:data => { :confirm => "Are you sure you want to delete this comment?" }
- if likes.count > 0
.comment-likes
- likers = likes.map { |like| link_to(like.user_name, "#") }
- if likers.length > 1
- likers = likers.slice(0, likers.length - 1).join(", ").concat(" and " + likers.slice(-1))
- else
- likers = likers[0]
= "Liked by #{likers}".html_safe
app/controllers/comments_controller.rb
class CommentsController < BaseController
load_and_authorize_resource
def destroy
destroy!{ discussion_url(resource.discussion ) }
end
def like
comment_vote = resource.like current_user
Event.comment_liked!(comment_vote)
#redirect_to discussion_url(resource.discussion )
render :partial => "like"
comment_likes
end
def unlike
resource.unlike current_user
#redirect_to discussion_url(resource.discussion)
render :partial => "unlike"
comment_likes
end
def comment_likes
render :partial => "comment_likes"
end
end
and then the .js.erb files for like, unlike and comment_likes:
app/views/_like.js.erb
$(".comment-time a#like").html("<%= escape_javascript(render('.comment-time a#like'")
app/views/_unlike.js.erb
$(".comment-time a#unlike").html("<%= escape_javascript(render('.comment-time a#unlike'")
app/views/_comment_likes.js.erb
$(".comment-likes a##").html("<%= escape_javascript(render('.comment-likes a##'")
Currently clicking like will update the database but will not show the changes until a page refresh, I just want to refresh the individual div's with ajax. A little more information about the div's could help so the ruby creates the html and contained in that as an example is or when already liked I just need to refresh these divs to show the latest from the database aswell as which contains http://localhost:3000/comments/7/unlike 500 (Internal Server Error)"
The rest of the scripting has been done in coffeescript if that matters? I read that the controller functions should use .js.erb so hope this isn't affecting it all. (Im sure my js.erb's are wrong)
I'm not sure if this is the main problem but one thing to fix would be the render statement in your .js.erb files.
The Rails render method requires as its argument the erb template or action to render. When you call:
render('.comment-time a#unlike')
Rails will try to find a template with the name ".comment-time a#unlike" somewhere in your view path which will probably raise some kind of error. Make sure you pay attention to the difference between what's happening in your javascript (in the client) in your application (on the server.)
So one way to fix this would be as follows. First check what part of the view you want to update, for simplicity's sake because you already have the _comment partial let's use that. Second figure out which part in the dom it should replace, in your case the div with the current comment's ID. We can then do the following:
$("#comment-<%= #comment.id %>").replace_html(
"<%= escape_javascript render('comments/comment', :comment => #comment) %>"
);
This will render the _comment.html.erb partial in app/views/comments, insert the result (escaped) into the javascript in your (dis-)like.js.erb and send that back to the browser to execute. The browser will then replace_html on the comment's div (indicated by the ID.)
Because we're replacing the whole comment div you can use the same method for both like and dislike. If you need to save bandwidth you could fine tune it to only re-render the like button itself, but for now this will work.
The problem is your Controller does not know how to respond to the ajax request. By default the render method will render html.erb or in your case html.haml templates.
Unless you do something like:
respond_to do |format|
format.js { comment_likes }
end
Now if an ajax requests comes in the _comments_likes.js.erb template will be rendered.
If you have more of these ajaxy type questions there are efforts being put into rewriting the ajax guides for rails.
And by the by, please consider cleaning up your view.

Saving a web page as image

As a hobby project I am exploring the ways to save a web page (HTML) as image, mostly programatically using c/c++/javascript/java. Till now I have come across the following ways:
Get the IHTMLElement of page body and use it to query for IHTMLElementRender and then use its DrawToDC method (Ref: http://www.codeproject.com/KB/IP/htmlimagecapture.aspx ). But the problem is that it did not work for all the pages (mostly pages having embedded iframes).
Another way which i can think of is to use some web browser component and when the pages is fully loaded then capture it using BitBlt (Ref: http://msdn.microsoft.com/en-us/library/dd183370%28VS.85%29.aspx ). But the problem is that the page I have requested may be longer than my screen size and it will not fit into the web browser component.
Any direction/suggestion to resolve above issues or an alternative approach is greatly appreciated.
If you use Python, there's pywebshot and webkit2png. Both of them have some dependencies, though.
Edit: Oops, Python is not in your list of preferred languages. I'll leave this answer here anyway, because you said "mostly" and not "exclusively".
Another (somewhat roundabout) option would be to run a server like Tomcat and use Java to call a command-line tool to take a screenshot. Googling for "command line screenshot windows" comes up with some reasonable-looking possibilities. Besides running a server, though, I don't know a good way to run local executables from javascript. This method would make it cross-browser, though, which is a plus (just make an ajax call to the script when you want a screenshot).
Unfortunately I don't actually know how to deploy war files. It might be more trouble to use Tomcat; I mentioned it because Java was a preferred language. It would be fairly simple to run XAMPP and use this PHP snippet, and you wouldn't really have to learn php:
<?php
exec("/path/to/exec args");
?>
EDIT
You know, I'm not sure that really answers your question. It's one way, but it's coming at it from the JavaScript end rather than the scripting end. If you want to do it via scripting, you could always use Selenium. It supports capturing screenshots of an entire page, and can be controlled via Java.
Well finally able to crack it by going through these two articles:
http://www.codeproject.com/KB/GDI-plus/WebPageSnapshot.aspx [c# code - IE]
http://www.codeproject.com/KB/graphics/IECapture.aspx [c++ & GDI - IE]
Can't share the code, but the above two articles will give you the best possible solution.
Also have a look at:
https://addons.mozilla.org/en-US/firefox/addon/3408/ [firefox + javascript]
Above things are still ok. BUT not guaranteed to work always. Check the below link:
How do I render the scrollable regions of a canvas with IViewObject::Draw?
If you are OK using javascript for it, I suggest going with phantomjs
Example from http://fcargoet.evolix.net/
var page = new WebPage(),
address = 'http://dev.sencha.com/deploy/ext-4.0.7-gpl/examples/feed-viewer/feed-viewer.html';
page.viewportSize = {
width : 800,
height : 600
};
// define the components we want to capture
var components = [{
output : 'feed-viewer-left.png',
//ExtJS has a nice component query engine
selector : 'feedpanel'
},{
output : 'feed-viewer-preview-btn.png',
selector : 'feeddetail > feedgrid > toolbar > cycle'
},{
output : 'feed-viewer-collapsed.png',
//executed before the rendering
before : function(){
var panel = Ext.ComponentQuery.query('feedpanel')[0];
panel.animCollapse = false; // cancel animation, no need to wait before capture
panel.collapse();
},
selector : 'viewport'
}];
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
} else {
/*
* give some time to ExtJS to
* - render the application
* - load asynchronous data
*/
window.setTimeout(function () {
components.forEach(function(component){
//execute the before function
component.before && page.evaluate(component.before);
// get the rectangular area to capture
/*
* page.evaluate() is sandboxed
* so that 'component' is not defined.
*
* It should be possible to pass variables in phantomjs 1.5
* but for now, workaround!
*/
eval('function workaround(){ window.componentSelector = "' + component.selector + '";}')
page.evaluate(workaround);
var rect = page.evaluate(function(){
// find the component
var comp = Ext.ComponentQuery.query(window.componentSelector)[0];
// get its bounding box
var box = comp.el.getBox();
// box is {x, y, width, height}
// we want {top, left, width, height}
box.top = box.y;
box.left = box.x;
return box;
});
page.clipRect = rect;
page.render(component.output);
});
// job done, exit
phantom.exit();
}, 2000);
}
});

Are Java Applets unable to communicate with javascript within Firefox on Mac OS?

I have a java applet running in a browser that is calling some javascript functions and expecting a result from theses functions. This is working with the following configurations :
Internet Explorer
FireFox / Windows
Safari / Mac
BUT It's not working with Firefox on MAC OS
The source of the problem seems to be the win.eval calls that always return null.
I tested this with Firefox 3.0.6 on a Mac OS X 10.4.11
A bit of code :
JSObject win = (JSObject) JSObject.getWindow(this);
Object exp = win.eval("testfunc()");
System.out.println("exp = " + exp.toString());
This triggers a java.lang.NullPointerException (exp.toString()) statement).
The testfunc javascript function just returns true.
I tried with win.call and got the same result.
My applet tag includes the mayscript and scriptable attributes.
I found the answer thanks to Tristan. Testing his solution I created a really simple test that could work and worked my way to find the culprit. I was sure I did my tests with an empty testfunc() that just returned true, but I probably didn't because in that case it DOES work.
The real problem here was that the function called a public method of the applet. Liveconnect doesn't seem to be able to handle that case in Firefox Mac.
Let me give you an example :
Java class :
public class MyApplet extends Applet {
public int getMyValue() {
return 5;
}
public void somefunction() {
JSObject win = (JSObject) JSObject.getWindow(this);
Object exp = win.eval("jsfunc()");
System.out.println("exp = " + exp.toString());
}
}
And the javascript code :
function jsfunc() {
var myApplet = document.getElementById("applet_id");
return myApplet.getMyValue() + 5;
}
exp will be null in somefunction BECAUSE jsfunc calls the getMyValue() method of the applet. If you remove all calls to properties of the applet you're cool.
To solve my problem I decided to give all the values of the applet that I neeeded as parameters of my javascript function and I'm good now.
That may not be the case always, if the javascript changes the state of the applet ...I was lucky :)
I haven't used the applet api in a while but if i recall correctly in order to allow an Applet to cann JS code you should enable the attribute mayscript in your applet tag or a param mayscript in the object tag notation.
For communication in the other way JS to Applet you should also use the scriptable attribute or parameter, for example:
<applet code="..." mayscript="true" />
This allows your applet to use script functions.
<applet code="..." scriptable="true" />
Would it work via accessing one of the global objects on the screen? Ergo,
In JavaScript:
window.testfunc = function() { //... }
In Applet:
win.eval("window.testfunc()") // or maybe just win.eval("testfunc()")
That would be my experiment. But I've been calling "window.close()" on FF on Mac OS X, and that still works.
If you remove all calls to properties of the applet you're cool.
This may happen in other situations as well. I found this page after Googling a similar problem, so I thought I'd add a datapoint. The only difference is that I was using win.call() rather than win.eval().
I had an alert() call in the JavaScript to make sure the call was getting through, and saw what appears to be exactly the same lockup on Firefox 3.0.9, OS X 10.5.6, Java 1.5.0_16. 100% repeatable with Firefox, no problem on Safari (I don't have Windows installed on this box).
When I got rid of the alert() and simply returned a value, the problem went away.
Sooooo... maybe calls into JavaScript time out after a while and simply toss null?

Categories

Resources