Discussion:
JSVGComponent dynamic DOM update, invokeAndWait threading issue
George Armhold
2003-09-18 17:21:41 UTC
Permalink
Hi all,

I'm trying to resolve a threading problem in my app. I'm using
JSVGComponent to display an SVG doc and dynamically update it in
response to AWT events (mouse drag/release results in adding <line>
elements to the DOM.) This generally works well. However I
occasionally run into a problem when loading a new document into the
JSVGComponent when DOM updates are apparently in-progress. The
scenario is the following:

- document load initiated via JSVGComponent.loadSVGDocument().

- I get an UpdateManagerListener event indicating that the doc is
available for updates, so I enable my drawing code.

- MouseDown event; user draws some line segments via the mouse in AWT
graphics.

- MouseReleased event; I add all my <line> elements to the document.
I do this in the UpdateManager's RunnableQueue via something like
the following:

// running in Swing/AWT thread after MouseReleased event
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
rq.invokeAndWait(new Runnable() {
public void run(){
// add my elements to the DOM
}
});

- user initiates loading of a new SVG doc by clicking a Swing button.


This usually works. However sometimes I find that getUpdateManager()
returns null, or that the RunnableQueue is not started. This tends to
happen when the user draws LOTS of line segments, resulting in many
DOM elements to be added. I *think* that what's happening is that a
new SVG doc load request is being initiated by the user before the
elements are finished being added to the DOM in my run() method. This
is a bit baffling to me, as the Swing/AWT thread should block on
invokeAndWait() before processing the "load new document" button
click. This problem is hard to reproduce because of the timing
involved. Also sometimes I find that I am able to hang the entire GUI
by this process.

So I guess my question is the following: how can I dynamically and
synchronously update the DOM via Swing/AWT events? I need to block
until the update completes. Is invokeAndWait "bad"? There is some
discussion about this in the following thread:

http://koala.ilog.fr/cgi-bin/batik-users-search-grep?rule=ci&target=invokeAndWait+%7C+invokeLater

Thanks very much for your time.


PS: this is all with Batik-1.5 built from CVS on 20-Aug-2003 and JDK
1.4.2.
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-18 18:19:55 UTC
Permalink
Hi George,
Post by George Armhold
I'm trying to resolve a threading problem in my app. I'm using
JSVGComponent to display an SVG doc and dynamically update it in
response to AWT events (mouse drag/release results in adding <line>
elements to the DOM.) This generally works well. However I
occasionally run into a problem when loading a new document into the
JSVGComponent when DOM updates are apparently in-progress. The
- document load initiated via JSVGComponent.loadSVGDocument().
- I get an UpdateManagerListener event indicating that the doc is
available for updates, so I enable my drawing code.
- MouseDown event; user draws some line segments via the mouse in AWT
graphics.
- MouseReleased event; I add all my <line> elements to the document.
I do this in the UpdateManager's RunnableQueue via something like
// running in Swing/AWT thread after MouseReleased event
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
rq.invokeAndWait(new Runnable() {
public void run(){
// add my elements to the DOM
}
});
- user initiates loading of a new SVG doc by clicking a Swing button.
This usually works. However sometimes I find that getUpdateManager()
returns null, or that the RunnableQueue is not started.
This would indicate to me that the MouseReleased code is running
after the load event (the getUpdateManager call is before the call to
invokeAndWait so it's hard to blame a null return from getUM on invokeAndWait :).
I would suggest inserting System.err messages so you can find out which
code runs when in these cases. The JSVGCanvas tries to be very good about
this cases so even if you did an invokeLater it should wait until your
runnable ends before disposing of the document.

Just picking on words here you say "after MouseReleased event" is this
happening _in_ the mouseRelease callback, or is it code triggered by the
mouse release callback?
Post by George Armhold
This tends to happen when the user draws LOTS of line segments, resulting in many
DOM elements to be added. I *think* that what's happening is that a
new SVG doc load request is being initiated by the user before the
elements are finished being added to the DOM in my run() method. This
is a bit baffling to me, as the Swing/AWT thread should block on
invokeAndWait() before processing the "load new document" button
click. This problem is hard to reproduce because of the timing
involved. Also sometimes I find that I am able to hang the entire GUI
by this process.
So I guess my question is the following: how can I dynamically and
synchronously update the DOM via Swing/AWT events? I need to block
until the update completes.
The above should do it (although I really suspect that you don't
need to block in this case if you are just throwing away the document
anyway).
Post by George Armhold
Is invokeAndWait "bad"? There is some
http://koala.ilog.fr/cgi-bin/batik-users-search-grep?rule=ci&target=invokeAndWait+%7C+invokeLater
Yes invokeAndWait from the AWT thread is bad because some DOM calls
require calling back to the AWT thread which will cause a deadlock. You
can safely use it from a third thread. But this is _not_ the issue you are
having (well it might be the freeze issue).
Post by George Armhold
Thanks very much for your time.
PS: this is all with Batik-1.5 built from CVS on 20-Aug-2003 and JDK
1.4.2.
George Armhold
2003-09-18 18:58:30 UTC
Permalink
Thomas,

Thanks again for yet another speedy response.
Post by Thomas DeWeese
This would indicate to me that the MouseReleased code is running
after the load event (the getUpdateManager call is before the call
to invokeAndWait so it's hard to blame a null return from getUM on
invokeAndWait :).
Yes, it sure looks that way. But assuming that Swing fires event
sequentially, it should mirror what the user is doing- MousePressed,
MouseDragged, MouseReleased, click on "load new SVG" button.
Post by Thomas DeWeese
The JSVGCanvas tries to be very good about this cases so even if you
did an invokeLater it should wait until your runnable ends before
disposing of the document.
OK, good to know that.
Post by Thomas DeWeese
Just picking on words here you say "after MouseReleased event" is
this happening _in_ the mouseRelease callback, or is it code
triggered by the mouse release callback?
Oops. I should have said that the code is called INSIDE the
MouseReleased callback. So the call to "invokeAndWait" is running in
the Swing/AWT thread.
Post by Thomas DeWeese
Post by George Armhold
So I guess my question is the following: how can I dynamically and
synchronously update the DOM via Swing/AWT events? I need to block
until the update completes.
The above should do it (although I really suspect that you don't
need to block in this case if you are just throwing away the document
anyway).
Well the problem is that I'm not throwing the document away. It's
true that if the user loads a new doc before the screen is done
updating from the new DOM elements, this presents no crisis. However
I *do* care that the doc is properly updated, because I then retrieve
the doc from the JSVGComponent and save it to disk, with the newly
added <line> elements. This is why I was trying to make the Swing
thread block until the DOM was updated- to prevent the user from being
able to click the "load new document" button until all elements were
added.
Post by Thomas DeWeese
Yes invokeAndWait from the AWT thread is bad because some DOM calls
require calling back to the AWT thread which will cause a deadlock.
You can safely use it from a third thread. But this is _not_ the
issue you are having (well it might be the freeze issue).
OK this explains my GUI hangs then. I don't recall seeing them when I
was doing invokeLater.
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-18 19:08:37 UTC
Permalink
Post by George Armhold
Thomas,
Thanks again for yet another speedy response.
Post by Thomas DeWeese
This would indicate to me that the MouseReleased code is running
after the load event (the getUpdateManager call is before the call
to invokeAndWait so it's hard to blame a null return from getUM on
invokeAndWait :).
Yes, it sure looks that way. But assuming that Swing fires event
sequentially, it should mirror what the user is doing- MousePressed,
MouseDragged, MouseReleased, click on "load new SVG" button.
This is why I would put print statements in the event handlers.
I suspect something 'surprising' happening in the event handing...
Post by George Armhold
Post by Thomas DeWeese
Just picking on words here you say "after MouseReleased event" is
this happening _in_ the mouseRelease callback, or is it code
triggered by the mouse release callback?
Oops. I should have said that the code is called INSIDE the
MouseReleased callback. So the call to "invokeAndWait" is running in
the Swing/AWT thread.
Any possability that the mouse release is the release from the
user pressing the 'load' button?
Post by George Armhold
Post by Thomas DeWeese
Post by George Armhold
So I guess my question is the following: how can I dynamically and
synchronously update the DOM via Swing/AWT events? I need to block
until the update completes.
The above should do it (although I really suspect that you don't
need to block in this case if you are just throwing away the document
anyway).
Well the problem is that I'm not throwing the document away. It's
true that if the user loads a new doc before the screen is done
updating from the new DOM elements, this presents no crisis. However
I *do* care that the doc is properly updated, because I then retrieve
the doc from the JSVGComponent and save it to disk, with the newly
added <line> elements.
Ok A word of caution on my previous assurences about 'good behaviour'
The canvas will make sure that the any currently running update completes
but I do not think it will run the Update Manager queue to empty.
Post by George Armhold
This is why I was trying to make the Swing
thread block until the DOM was updated- to prevent the user from being
able to click the "load new document" button until all elements were
added.
My suspicion is that you have succeeded in this and that you are picking
up another mouse up somewhere along the line.
George Armhold
2003-09-18 20:47:24 UTC
Permalink
This is why I would put print statements in the event handlers. I
suspect something 'surprising' happening in the event handing...
[ ... ]
Any possability that the mouse release is the release from the user
pressing the 'load' button?
I instrumented the code as you suggested. The MouseReleased event is
only coming from the JSVGComponent; ie I am NOT getting MouseReleased
from the "load svg doc" button. Too bad, would have been an easy
fix. :-)

However I did notice that the events (Swing & UpdateManagerListener)
are coming in rather strangely. I am seeing the following:

mouseReleased
"load new doc" button pressed
updateStarted (UpdateManagerListener)
updateCompleted (UpdateManagerListener)
managerStopped (UpdateManagerListener)

I would have expected the "load new doc" line to be printed LAST. So
this would explain the occasional NullPointerException/RunnableQueue
not started exceptions. The question is: why is Swing seemingly not
blocking on invokeAndWait(), but rather allowing the multiple events
(MouseReleased, button press) to be fired before the update is
complete? Anyway, if calling invokeAndWait() from Swing/AWT events is
not recommended, I will have to change my approach.
Ok A word of caution on my previous assurences about 'good
behaviour' The canvas will make sure that the any currently running
update completes but I do not think it will run the Update Manager
queue to empty.
So this means that any currently running "runnable" will finish, but
the queue will not be emptied of all such runnables?
Post by George Armhold
This is why I was trying to make the Swing
thread block until the DOM was updated- to prevent the user from being
able to click the "load new document" button until all elements were
added.
My suspicion is that you have succeeded in this and that you are picking
up another mouse up somewhere along the line.
I don't think that I've really succeeded if the invokeAndWait needs to
be removed. I will have to figure out how to make this work with
invokeLater.

Thanks again for your help.
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-18 21:24:16 UTC
Permalink
Post by George Armhold
This is why I would put print statements in the event handlers. I
suspect something 'surprising' happening in the event handing...
[ ... ]
Any possability that the mouse release is the release from the user
pressing the 'load' button?
I instrumented the code as you suggested. The MouseReleased event is
only coming from the JSVGComponent; ie I am NOT getting MouseReleased
from the "load svg doc" button. Too bad, would have been an easy
fix. :-)
However I did notice that the events (Swing & UpdateManagerListener)
mouseReleased
"load new doc" button pressed
updateStarted (UpdateManagerListener)
updateCompleted (UpdateManagerListener)
managerStopped (UpdateManagerListener)
Hmm, Do you have a 'mouseRelease done' message at the end of the event handler?
Post by George Armhold
I would have expected the "load new doc" line to be printed LAST. So
this would explain the occasional NullPointerException/RunnableQueue
not started exceptions. The question is: why is Swing seemingly not
blocking on invokeAndWait(), but rather allowing the multiple events
(MouseReleased, button press) to be fired before the update is
complete? Anyway, if calling invokeAndWait() from Swing/AWT events is
not recommended, I will have to change my approach.
You could check the current thread see what threads are being used where.
Post by George Armhold
Ok A word of caution on my previous assurences about 'good
behaviour' The canvas will make sure that the any currently running
update completes but I do not think it will run the Update Manager
queue to empty.
So this means that any currently running "runnable" will finish, but
the queue will not be emptied of all such runnables?
100% correct.
Post by George Armhold
Post by George Armhold
This is why I was trying to make the Swing
thread block until the DOM was updated- to prevent the user from being
able to click the "load new document" button until all elements were
added.
My suspicion is that you have succeeded in this and that you are picking
up another mouse up somewhere along the line.
I don't think that I've really succeeded if the invokeAndWait needs to
be removed. I will have to figure out how to make this work with
invokeLater.
It would be best to. You will probably have to 'delay' the load
document call until the current document is 'done'.
George Armhold
2003-09-19 00:03:37 UTC
Permalink
Hmmm,

I changed my invokeAndWait to an invokeLater and now I am getting
ConcurrentModificationExceptions in the UpdateManager. I love threads.
:-) Is it OK to do things like create elements from the SVG Document
outside of the UpdateManager's RunnableQueue? What I'm doing currently
is creating my new elements and setting their attributes in the Swing
thread, and then adding them to the DOM in the UpdateManager's
RunnableQueue. Is this legit?

Thanks.
Thomas DeWeese
2003-09-19 10:30:27 UTC
Permalink
Post by George Armhold
Hmmm,
I changed my invokeAndWait to an invokeLater and now I am getting
ConcurrentModificationExceptions in the UpdateManager. I love threads.
:-)
Can you provide stack traces? I'm surprised to see this as the
UpdateManager is supposed to be thread safe.
Post by George Armhold
Is it OK to do things like create elements from the SVG Document
outside of the UpdateManager's RunnableQueue? What I'm doing currently
is creating my new elements and setting their attributes in the Swing
thread, and then adding them to the DOM in the UpdateManager's
RunnableQueue. Is this legit?
This is not 100% legit, it will probably work but just as an example
of the sorts of things that can cause problems - the Document caches
the responses to getElementsByTagName and maintians the list as elements
are added/removed (it might do something similar for 'getElementById' in
the future). Now these wouldn't effect you because they only apply
to elements that are in the document - but right now our document
implementation is 100% unthread-safe so I hesitate to say that it is
safe or will always stay safe.
George Armhold
2003-09-19 14:55:00 UTC
Permalink
Post by Thomas DeWeese
Can you provide stack traces? I'm surprised to see this as the
UpdateManager is supposed to be thread safe.
Sure, here's my jws.log. Sorry for all the extraneous junk, but I
didn't want to remove anything potentially useful from the output.
Note that this is with invokeLater. Also the later exceptions can
probably be ignored- after the ConcurrentModificationException the app
is hopelessly confused.

Thanks again for your continued assistance with this.


Presenter starting...
tmpDir: C:\DOCUME~1\armhold\LOCALS~1\Temp\elearn.dir
mixer: Java Sound Audio Engine, version 1.0
line: interface SourceDataLine supporting 8 audio formats
format: PCM_SIGNED, 44100.0 Hz, 16 bit, stereo, little-endian, audio data
line: interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes
format: PCM_SIGNED, 44100.0 Hz, 16 bit, stereo, little-endian, audio data
mixer: Microsoft Sound Mapper, version Unknown Version
mixer: YAMAHA AC-XG WDM Audio, version Unknown Version
mixer: YAMAHA AC-XG WDM Audio, version 5.10
line: Mono Mix source port
line: Stereo Mix source port
line: COMPACT_DISC source port
line: LINE_IN source port
line: MICROPHONE source port
target format: PCM_SIGNED, 11025.0 Hz, 16 bit, mono, little-endian, audio data
bytesPerSample: 2
bytesPerSecond: 22050
Supported target types: au aif wav
getXMLParserClassName=org.apache.xerces.parsers.SAXParser
recordingProfile.type: whiteboard
getScribbleGroup(): calling newScribbleGroup()
TableOfContents: rendering file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
rasterizing URL: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
img data len: 206
loading: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
ScribbleComponent.beginRecording()
controls:
WavFile::createNewFile(): open wavFile=C:\Documents and Settings\armhold\Desktop\timing tests\New Folder\audio.wav, wavFileLen=0
lineBufferSize: 11024
buf size: 44096
svgLoadEventDispatchStarted
managerStarted
beginRecording
mousePressed: edu.rutgers.elearning.scribble.ScribbleComponent[,115,0,809x500,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=768,height=480]]
mouseReleased: edu.rutgers.elearning.scribble.ScribbleComponent[,115,0,809x500,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=768,height=480]]
next button pressed: java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=Next,when=1063929293658,modifiers=Button1] on javax.swing.JButton[,75,0,55x23,layout=javax.swing.OverlayLayout,alignmentX=0.0,alignmentY=0.5,border=com.sun.java.swing.plaf.windows.XPStyle$***@1438dbe,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Next,defaultCapable=true]
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at org.apache.batik.gvt.UpdateTracker.getDirtyAreas(Unknown Source)
at org.apache.batik.bridge.UpdateManager.repaint(Unknown Source)
at org.apache.batik.bridge.UpdateManager.runnableInvoked(Unknown Source)
at org.apache.batik.util.RunnableQueue.runnableInvoked(Unknown Source)
at org.apache.batik.util.RunnableQueue.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
getScribbleGroup(): calling newScribbleGroup()
loading: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
TableOfContents: rendering file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
rasterizing URL: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
img data len: 206
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(Unknown Source)
at org.apache.batik.swing.svg.JSVGComponent$SVGListener.dispatchMouseEntered(Unknown Source)
at org.apache.batik.swing.gvt.JGVTComponent$Listener.mouseEntered(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-19 18:16:12 UTC
Permalink
Hi George,

So it looks like someone is modifing the document outside of the
update manager thread. The exception is happening in the dirty
region management - the repaint is trying to collect the dirty
regions (from the update manager thread) and someone has undoubtably
added a new dirty region to the 'list' - which means that someone
modified the rendering tree outside of the update manager thread.

Unfortunately the thread that has the exception is the 'good thread'
not the 'bad thread'. You might try adding code to the UpdateTracker
to print a stack trace if it is called from outside the UpdateManager
thread (specifcally the changeStarted method).
Post by George Armhold
Post by Thomas DeWeese
Can you provide stack traces? I'm surprised to see this as the
UpdateManager is supposed to be thread safe.
Sure, here's my jws.log. Sorry for all the extraneous junk, but I
didn't want to remove anything potentially useful from the output.
Note that this is with invokeLater. Also the later exceptions can
probably be ignored- after the ConcurrentModificationException the app
is hopelessly confused.
Thanks again for your continued assistance with this.
Presenter starting...
tmpDir: C:\DOCUME~1\armhold\LOCALS~1\Temp\elearn.dir
mixer: Java Sound Audio Engine, version 1.0
line: interface SourceDataLine supporting 8 audio formats
format: PCM_SIGNED, 44100.0 Hz, 16 bit, stereo, little-endian, audio data
line: interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes
format: PCM_SIGNED, 44100.0 Hz, 16 bit, stereo, little-endian, audio data
mixer: Microsoft Sound Mapper, version Unknown Version
mixer: YAMAHA AC-XG WDM Audio, version Unknown Version
mixer: YAMAHA AC-XG WDM Audio, version 5.10
line: Mono Mix source port
line: Stereo Mix source port
line: COMPACT_DISC source port
line: LINE_IN source port
line: MICROPHONE source port
target format: PCM_SIGNED, 11025.0 Hz, 16 bit, mono, little-endian, audio data
bytesPerSample: 2
bytesPerSecond: 22050
Supported target types: au aif wav
getXMLParserClassName=org.apache.xerces.parsers.SAXParser
recordingProfile.type: whiteboard
getScribbleGroup(): calling newScribbleGroup()
TableOfContents: rendering
file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
img data len: 206
loading: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/page1.svg9284
ScribbleComponent.beginRecording()
WavFile::createNewFile(): open wavFile=C:\Documents and
Settings\armhold\Desktop\timing tests\New Folder\audio.wav, wavFileLen=0
lineBufferSize: 11024
buf size: 44096
svgLoadEventDispatchStarted
managerStarted
beginRecording
edu.rutgers.elearning.scribble.ScribbleComponent[,115,0,809x500,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=768,height=480]]
edu.rutgers.elearning.scribble.ScribbleComponent[,115,0,809x500,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=768,height=480]]
java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=Next,when=1063929293658,modifiers=Button1]
on
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at org.apache.batik.gvt.UpdateTracker.getDirtyAreas(Unknown Source)
at org.apache.batik.bridge.UpdateManager.repaint(Unknown Source)
at org.apache.batik.bridge.UpdateManager.runnableInvoked(Unknown Source)
at org.apache.batik.util.RunnableQueue.runnableInvoked(Unknown Source)
at org.apache.batik.util.RunnableQueue.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
getScribbleGroup(): calling newScribbleGroup()
loading: file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
TableOfContents: rendering
file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
file:/C:/DOCUME~1/armhold/LOCALS~1/Temp/elearn.dir/slide2.svg
George Armhold
2003-09-19 16:54:24 UTC
Permalink
Post by Thomas DeWeese
Post by George Armhold
ConcurrentModificationExceptions in the UpdateManager. I love
threads. :-)
Can you provide stack traces? I'm surprised to see this as the
UpdateManager is supposed to be thread safe.
As a non-expert I just took a quick look at the latest Batik CVS
source. The UpdateManager's repaint() method looks like it needs a
synchronized block around its iterator. Also UpdateTracker.java (used
by UpdateManager) seems to use lots of unsynchronized collections.
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-19 18:35:16 UTC
Permalink
Post by George Armhold
Post by Thomas DeWeese
Post by George Armhold
ConcurrentModificationExceptions in the UpdateManager. I love
threads. :-)
Can you provide stack traces? I'm surprised to see this as the
UpdateManager is supposed to be thread safe.
As a non-expert I just took a quick look at the latest Batik CVS
source. The UpdateManager's repaint() method looks like it needs a
synchronized block around its iterator. Also UpdateTracker.java (used
by UpdateManager) seems to use lots of unsynchronized collections.
Well the UpdateTracker is _not_ intended to be thread safe.
I'm not sure if the UpdateManager.repaint needs to be (in
other words does it have to support being called from
multiple threads concurrently) but I agree that locking on
the runnableQueue list is important - and that should have the
side effect of making it thread safe. Thanks!
George Armhold
2003-09-19 00:32:40 UTC
Permalink
Post by Thomas DeWeese
Post by George Armhold
mouseReleased
"load new doc" button pressed
updateStarted (UpdateManagerListener)
updateCompleted (UpdateManagerListener)
managerStopped (UpdateManagerListener)
Hmm, Do you have a 'mouseRelease done' message at the end of the event handler?
I do now. It looks like this:

mousePressed entered
mousePressed exited
mouseReleased entered
mouseReleased exited
updateStarted (UpdateManagerListener)
updateCompleted (UpdateManagerListener)

Interestingly I get the same sequence with invokeAndWait vs invokeLater.
Perhaps the events from the UpdateManager only indicate that screen
updates have begun/finished, rather than the DOM elements being added?
Thomas DeWeese
2003-09-19 10:21:01 UTC
Permalink
Post by George Armhold
Post by Thomas DeWeese
Hmm, Do you have a 'mouseRelease done' message at the end of the event handler?
mousePressed entered
mousePressed exited
mouseReleased entered
mouseReleased exited
updateStarted (UpdateManagerListener)
updateCompleted (UpdateManagerListener)
Interestingly I get the same sequence with invokeAndWait vs invokeLater.
Perhaps the events from the UpdateManager only indicate that screen
updates have begun/finished, rather than the DOM elements being added?
Ahh, yes! The update stuff you are seeing is the 'repaint' of the
GVT tree - that also happens in the AWT thread but it is enqueued after
the runnable completes. So a longer runnable could delay the enqueue
until after the user presses 'load'. The question then is why were you
getting Null UpdateManager?
George Armhold
2003-09-19 20:49:55 UTC
Permalink
Post by Thomas DeWeese
Ahh, yes! The update stuff you are seeing is the 'repaint' of the
GVT tree - that also happens in the AWT thread but it is enqueued
after the runnable completes. So a longer runnable could delay the
enqueue until after the user presses 'load'. The question then is
why were you getting Null UpdateManager?
OK, I think we are finally closing in on the problem. I was assuming
that when my UpdateManagerListener.managerStarted() was fired, that
meant that the RunnableQueue was then available. I guess this really
just means that the manager for screen updates is now running. So
now my question is: how can I know when it's safe to call

UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();

and add things to the RunnableQueue?
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-09-19 22:06:50 UTC
Permalink
Post by George Armhold
Post by Thomas DeWeese
Ahh, yes! The update stuff you are seeing is the 'repaint' of the
GVT tree - that also happens in the AWT thread but it is enqueued
after the runnable completes. So a longer runnable could delay the
enqueue until after the user presses 'load'. The question then is
why were you getting Null UpdateManager?
OK, I think we are finally closing in on the problem. I was assuming
that when my UpdateManagerListener.managerStarted() was fired, that
meant that the RunnableQueue was then available. I guess this really
just means that the manager for screen updates is now running.
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes.
This is _before_ the managerStarted call back, so this
shouldn't be the problem. You should have enough
instrumentation in your code now to figure out what
the sequence of events is that leads
to the Null UpdateManager is.
George Armhold
2003-09-29 19:29:11 UTC
Permalink
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
code:

- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.

- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.


Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!


--
George Armhold
Rutgers University
eLearning Grant, DCIS
Denis Bohm
2003-10-01 02:59:33 UTC
Permalink
I'm having a problem reloading a document. The first time I try to reload I
just get a blank page, on the second try to reload it seems to work. But
sometimes on the second reload I get:

java.lang.IllegalStateException: RunnableQueue not started or has exited
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)

and things don't function anymore.

I assume that I need to shut somethings down before changing the document?
Is that what you are referring to when you say "don't load new SVG documents
until pending DOM updates"?

Thanks,
Denis

----- Original Message -----
From: "George Armhold" <***@cs.rutgers.edu>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
Denis Bohm
2003-10-01 04:25:57 UTC
Permalink
I'm trying to script using Java according to the SVG 1.1 specification:

http://www.w3.org/TR/SVG11/java.html

But when I try to load my demo.svg file into Squiggle I get:

"SVG Error: com.fireflydesign.svg.SVGHandler

java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."

I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?

Thanks,
Denis


Here is my SVG (demo.svg):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>

Here is my manifest:

Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler


And my Java source:

package com.fireflydesign.svg;

import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;

import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;

public class SVGHandler implements EventListenerInitializer {

public SVGHandler() {
}

public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}

}
Christophe Jolif
2003-10-01 09:10:49 UTC
Permalink
Denis,

This is working fine for me. Which version of Batik are you using? You need at
least 1.5 (not a beta).
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
---------------------------------------------------------------------
--
Christophe
Denis Bohm
2003-10-01 17:43:30 UTC
Permalink
Hi,

Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(

Denis

----- Original Message -----
From: "Christophe Jolif" <***@ilog.fr>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You need at
least 1.5 (not a beta).
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
---------------------------------------------------------------------
--
Christophe
---------------------------------------------------------------------
Thomas DeWeese
2003-10-01 17:52:34 UTC
Permalink
Hi,

Perhaps you have security settings set differently in Squiggle.
Preferences->Browser Options->Security Settings
Post by Denis Bohm
Hi,
Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You
need at
Post by Christophe Jolif
least 1.5 (not a beta).
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
---------------------------------------------------------------------
--
Christophe
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 18:32:23 UTC
Permalink
I tried all the different settings and don't see any difference - still the
same error.

I tried to run squiggle from Forte in the debugger, but I get:

java.lang.Error
at
org.apache.batik.util.ApplicationSecurityEnforcer.setDevBase(ApplicationSecu
rityEnforcer.java:345)
at
org.apache.batik.util.ApplicationSecurityEnforcer.installSecurityManager(App
licationSecurityEnforcer.java:276)
at
org.apache.batik.util.ApplicationSecurityEnforcer.enforceSecurity(Applicatio
nSecurityEnforcer.java:203)
at
org.apache.batik.apps.svgbrowser.Main.setPreferences(Main.java:709)
at org.apache.batik.apps.svgbrowser.Main.<init>(Main.java:347)
at org.apache.batik.apps.svgbrowser.Main.main(Main.java:190)
Exception in thread "main"

Do I need to specify some command line args to squiggle so that it can be
run from the debugger?

----- Original Message -----
From: "Thomas DeWeese" <***@Kodak.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 10:52 AM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Hi,
Perhaps you have security settings set differently in Squiggle.
Preferences->Browser Options->Security Settings
Post by Denis Bohm
Hi,
Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You
need at
Post by Christophe Jolif
least 1.5 (not a beta).
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class.
Anyone
Post by Thomas DeWeese
Post by Denis Bohm
Post by Christophe Jolif
Post by Denis Bohm
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
Post by Denis Bohm
---------------------------------------------------------------------
--
Christophe
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Thomas DeWeese
2003-10-01 19:25:55 UTC
Permalink
Actually I think the problem may be with forte.
The batik security policy needs to know the root
of the Batik 'distribution' so it can grant appropriate
permissions.

The way it does this when running from class files
(it does something different for jar files) is
it get's the URL to one of the class files and
looks for 'classes/org/apache/batik/...' in that path
it then makes the parent of 'classes' the root of the
distribution.

When running in Forte it appears that either this URL is strange
or it doesn't include 'classes'.
Post by Denis Bohm
I tried all the different settings and don't see any difference - still the
same error.
java.lang.Error
at
org.apache.batik.util.ApplicationSecurityEnforcer.setDevBase(ApplicationSecu
rityEnforcer.java:345)
at
org.apache.batik.util.ApplicationSecurityEnforcer.installSecurityManager(App
licationSecurityEnforcer.java:276)
at
org.apache.batik.util.ApplicationSecurityEnforcer.enforceSecurity(Applicatio
nSecurityEnforcer.java:203)
at
org.apache.batik.apps.svgbrowser.Main.setPreferences(Main.java:709)
at org.apache.batik.apps.svgbrowser.Main.<init>(Main.java:347)
at org.apache.batik.apps.svgbrowser.Main.main(Main.java:190)
Exception in thread "main"
Do I need to specify some command line args to squiggle so that it can be
run from the debugger?
----- Original Message -----
Sent: Wednesday, October 01, 2003 10:52 AM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Hi,
Perhaps you have security settings set differently in Squiggle.
Preferences->Browser Options->Security Settings
Post by Denis Bohm
Hi,
Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You
need at
Post by Christophe Jolif
least 1.5 (not a beta).
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class.
Anyone
Post by Thomas DeWeese
Post by Denis Bohm
Post by Christophe Jolif
Post by Denis Bohm
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
Post by Denis Bohm
---------------------------------------------------------------------
--
Christophe
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 20:34:36 UTC
Permalink
The default with my setup is that the clases go into the sources tree, so I
added another check for that in setDevBase and added a new permission entry
for sources. Now it gets farther and I see the error shown below. Any idea
why that one is happening?

java.lang.NoSuchFieldError: OPACITY
at
org.apache.batik.bridge.SVGTextElementBridge.addPaintAttributes(SVGTextEleme
ntBridge.java:1264)
at
org.apache.batik.bridge.SVGTextElementBridge.computeLayoutedText(SVGTextElem
entBridge.java:524)
at
org.apache.batik.bridge.SVGTextElementBridge.buildGraphicsNode(SVGTextElemen
tBridge.java:222)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:160)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:158)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:226)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:158)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:108)
at
org.apache.batik.swing.svg.GVTTreeBuilder.run(GVTTreeBuilder.java:136)

----- Original Message -----
From: "Thomas DeWeese" <***@Kodak.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 12:25 PM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Actually I think the problem may be with forte.
The batik security policy needs to know the root
of the Batik 'distribution' so it can grant appropriate
permissions.
The way it does this when running from class files
(it does something different for jar files) is
it get's the URL to one of the class files and
looks for 'classes/org/apache/batik/...' in that path
it then makes the parent of 'classes' the root of the
distribution.
When running in Forte it appears that either this URL is strange
or it doesn't include 'classes'.
Post by Denis Bohm
I tried all the different settings and don't see any difference - still the
same error.
java.lang.Error
at
org.apache.batik.util.ApplicationSecurityEnforcer.setDevBase(ApplicationSecu
Post by Thomas DeWeese
Post by Denis Bohm
rityEnforcer.java:345)
at
org.apache.batik.util.ApplicationSecurityEnforcer.installSecurityManager(App
Post by Thomas DeWeese
Post by Denis Bohm
licationSecurityEnforcer.java:276)
at
org.apache.batik.util.ApplicationSecurityEnforcer.enforceSecurity(Applicatio
Post by Thomas DeWeese
Post by Denis Bohm
nSecurityEnforcer.java:203)
at
org.apache.batik.apps.svgbrowser.Main.setPreferences(Main.java:709)
at org.apache.batik.apps.svgbrowser.Main.<init>(Main.java:347)
at org.apache.batik.apps.svgbrowser.Main.main(Main.java:190)
Exception in thread "main"
Do I need to specify some command line args to squiggle so that it can be
run from the debugger?
----- Original Message -----
Sent: Wednesday, October 01, 2003 10:52 AM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Hi,
Perhaps you have security settings set differently in Squiggle.
Preferences->Browser Options->Security Settings
Post by Denis Bohm
Hi,
Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You
need at
Post by Christophe Jolif
least 1.5 (not a beta).
Post by Denis Bohm
I'm trying to script using Java according to the SVG 1.1
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class.
Anyone
Post by Thomas DeWeese
Post by Denis Bohm
Post by Christophe Jolif
Post by Denis Bohm
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
Post by Christophe Jolif
Post by Denis Bohm
---------------------------------------------------------------------
--
Christophe
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 20:59:21 UTC
Permalink
Sorry - this was due to a build problem on my part. I have squiggle running
in the Forte debugger now.

----- Original Message -----
From: "Denis Bohm" <***@fireflydesign.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 1:34 PM
Subject: Re: Scripting with Java Error
Post by Denis Bohm
The default with my setup is that the clases go into the sources tree, so I
added another check for that in setDevBase and added a new permission entry
for sources. Now it gets farther and I see the error shown below. Any idea
why that one is happening?
java.lang.NoSuchFieldError: OPACITY
at
org.apache.batik.bridge.SVGTextElementBridge.addPaintAttributes(SVGTextEleme
Post by Denis Bohm
ntBridge.java:1264)
at
org.apache.batik.bridge.SVGTextElementBridge.computeLayoutedText(SVGTextElem
Post by Denis Bohm
entBridge.java:524)
at
org.apache.batik.bridge.SVGTextElementBridge.buildGraphicsNode(SVGTextElemen
Post by Denis Bohm
tBridge.java:222)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:160)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
Post by Denis Bohm
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Post by Denis Bohm
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:158)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
Post by Denis Bohm
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Post by Denis Bohm
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:226)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:158)
at
org.apache.batik.bridge.SVGUseElementBridge.buildCompositeGraphicsNode(SVGUs
Post by Denis Bohm
eElementBridge.java:209)
at
org.apache.batik.bridge.SVGUseElementBridge.createGraphicsNode(SVGUseElement
Post by Denis Bohm
Bridge.java:118)
at
org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:220)
at
org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:186)
at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:108)
at
org.apache.batik.swing.svg.GVTTreeBuilder.run(GVTTreeBuilder.java:136)
----- Original Message -----
Sent: Wednesday, October 01, 2003 12:25 PM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Actually I think the problem may be with forte.
The batik security policy needs to know the root
of the Batik 'distribution' so it can grant appropriate
permissions.
The way it does this when running from class files
(it does something different for jar files) is
it get's the URL to one of the class files and
looks for 'classes/org/apache/batik/...' in that path
it then makes the parent of 'classes' the root of the
distribution.
When running in Forte it appears that either this URL is strange
or it doesn't include 'classes'.
Post by Denis Bohm
I tried all the different settings and don't see any difference -
still
Post by Denis Bohm
the
Post by Thomas DeWeese
Post by Denis Bohm
same error.
java.lang.Error
at
org.apache.batik.util.ApplicationSecurityEnforcer.setDevBase(ApplicationSecu
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
rityEnforcer.java:345)
at
org.apache.batik.util.ApplicationSecurityEnforcer.installSecurityManager(App
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
licationSecurityEnforcer.java:276)
at
org.apache.batik.util.ApplicationSecurityEnforcer.enforceSecurity(Applicatio
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
nSecurityEnforcer.java:203)
at
org.apache.batik.apps.svgbrowser.Main.setPreferences(Main.java:709)
at org.apache.batik.apps.svgbrowser.Main.<init>(Main.java:347)
at org.apache.batik.apps.svgbrowser.Main.main(Main.java:190)
Exception in thread "main"
Do I need to specify some command line args to squiggle so that it can
be
Post by Thomas DeWeese
Post by Denis Bohm
run from the debugger?
----- Original Message -----
Sent: Wednesday, October 01, 2003 10:52 AM
Subject: Re: Scripting with Java Error
Post by Thomas DeWeese
Hi,
Perhaps you have security settings set differently in Squiggle.
Preferences->Browser Options->Security Settings
Post by Denis Bohm
Hi,
Glad to hear that it works for someone. I'm running out of a fresh CVS
checkout using 'ant squiggle'. Still not working for me... :^(
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:10 AM
Subject: Re: Scripting with Java Error
Post by Christophe Jolif
Denis,
This is working fine for me. Which version of Batik are you using? You
need at
Post by Christophe Jolif
least 1.5 (not a beta).
Post by Denis Bohm
I'm trying to script using Java according to the SVG 1.1
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class.
Anyone
Post by Thomas DeWeese
Post by Denis Bohm
Post by Christophe Jolif
Post by Denis Bohm
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
------------------------------------------------------------------------
Post by Denis Bohm
---------------------------------------------------------------------
Post by Christophe Jolif
--
Christophe
---------------------------------------------------------------------
Post by Denis Bohm
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 21:22:51 UTC
Permalink
I think the problem was that there was trailing whie space after the class
name. I removed that and now the Java class is loaded.

However, the onload event listener doesn't seem to be getting called...

----- Original Message -----
From: "Denis Bohm" <***@fireflydesign.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Tuesday, September 30, 2003 9:25 PM
Subject: Scripting with Java Error
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
----------------------------------------------------------------------------
----
Post by Denis Bohm
---------------------------------------------------------------------
Denis Bohm
2003-10-01 21:32:03 UTC
Permalink
Looks like my other problem was using "onload" rather than "SVGLoad".
Confusing since "onload" seemed to work from JavaScript...

So I'm running now.

----- Original Message -----
From: "Denis Bohm" <***@fireflydesign.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 2:22 PM
Subject: Re: Scripting with Java Error
Post by Denis Bohm
I think the problem was that there was trailing whie space after the class
name. I removed that and now the Java class is loaded.
However, the onload event listener doesn't seem to be getting called...
----- Original Message -----
Sent: Tuesday, September 30, 2003 9:25 PM
Subject: Scripting with Java Error
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
--------------------------------------------------------------------------
--
Post by Denis Bohm
----
Post by Denis Bohm
---------------------------------------------------------------------
---------------------------------------------------------------------
Thomas DeWeese
2003-10-01 21:36:06 UTC
Permalink
Post by Denis Bohm
I think the problem was that there was trailing whie space after the class
name. I removed that and now the Java class is loaded.
Good!
Post by Denis Bohm
However, the onload event listener doesn't seem to be getting called...
Check the spec, the DOM event names are not the same as the event attributes.
'onload' == 'SVGLoad' There is a table in an appendix that lists them all.
Post by Denis Bohm
----- Original Message -----
Sent: Tuesday, September 30, 2003 9:25 PM
Subject: Scripting with Java Error
Post by Denis Bohm
http://www.w3.org/TR/SVG11/java.html
"SVG Error: com.fireflydesign.svg.SVGHandler
java.lang.ClassNotFoundException: com.fireflydesign.svg.SVGHandler
..."
I checked the archive and it seems to contain the handler class. Anyone
have any idea why the class can't be found?
Thanks,
Denis
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
]>
<svg width="600" height="800" viewBox="0 0 600 800"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="demo.jar"/>
<text x="10" y="20" fill="black">Hello</text>
</svg>
Manifest-Version: 1.0
SVG-Handler-Class: com.fireflydesign.svg.SVGHandler
package com.fireflydesign.svg;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.svg.EventListenerInitializer;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
public class SVGHandler implements EventListenerInitializer {
public SVGHandler() {
}
public void initializeEventListeners(SVGDocument document) {
SVGSVGElement root = document.getRootElement();
EventListener listener = new EventListener() {
public void handleEvent(Event event) {
System.out.println("onload");
}
};
root.addEventListener("onload", listener, false);
}
}
----------------------------------------------------------------------------
----
Post by Denis Bohm
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 22:27:09 UTC
Permalink
I have an application that I would like to implement using SVG and the Java
Language Binding Scripting. I have an SVG document and a Java
EventListenerInitializer that is working in Squiggle. So far, so good. Now
I would like to sping off a thread that creates a socket connection and
listens for data. When the data arrives I would like to update the SVG DOM.
To do that I need to ask the Batik canvas for the update manager and ask
that for the runnable queue then queue up a runnable to do the update.
However, I don't have a reference to the canvas. Is there some way to get
one from the document?

I would also like my code to not use any Batik implementation specific stuff
(in the hope that other browsers will also support SVG with Java scripting).
So I took a look at the SVG 1.2 spec to see if there was some upcoming
standard way to do this. Section 11 talks about adding a SVGWindow
interface with a way to create SVGTimer objects that can run a set of
SVGRunnable objects. So it sounds like the following:

SVGDocument document = ?:
SVGWindow window = document.getSVGWindow();
SVGTimer timer = window.createTimer(0, false);
timer.addHandler(new SVGRunnable() {
public void run() {
}
});
timer.start();

will have the same effect as:

SVGCanvas canvas = ?;
UpdateManager updateManager = canvas.getUpdateManager();
RunnableQueue runnableQueue = updateManager.getRunnableQueue();
runnableQueue.invokeLater(new Runnable() {
public void run() {
}
});

but it could potentially run in other implementations. Does that sound
right?

BTW: It looks like adding these interfaces and an implementation that just
routes the calls the existing Batik code would be fairly straight forward.
Is there any interest in that?

Thanks,
Denis
Thomas DeWeese
2003-10-06 12:50:31 UTC
Permalink
Post by Denis Bohm
I have an application that I would like to implement using SVG and the Java
Language Binding Scripting. I have an SVG document and a Java
EventListenerInitializer that is working in Squiggle. So far, so good. Now
I would like to sping off a thread that creates a socket connection and
listens for data. When the data arrives I would like to update the SVG DOM.
To do that I need to ask the Batik canvas for the update manager and ask
that for the runnable queue then queue up a runnable to do the update.
However, I don't have a reference to the canvas. Is there some way to get
one from the document?
Well the Window object we provide has a method 'getBridgeContext' and
the BridgeContext can provide you with the UpdateManager (if there is one).
Post by Denis Bohm
I would also like my code to not use any Batik implementation specific stuff
(in the hope that other browsers will also support SVG with Java scripting).
The above is 100% pure Batik :)
Post by Denis Bohm
So I took a look at the SVG 1.2 spec to see if there was some upcoming
standard way to do this. Section 11 talks about adding a SVGWindow
interface with a way to create SVGTimer objects that can run a set of
[...]
Post by Denis Bohm
but it could potentially run in other implementations. Does that sound
right?
This might be a route to go. I suspect they WG is trying to
standardize on how to access the DOM in a multi-threaded environment,
so it may provide a less 'hacky' way to do this in the future.
Post by Denis Bohm
BTW: It looks like adding these interfaces and an implementation that just
routes the calls the existing Batik code would be fairly straight forward.
Is there any interest in that?
Contributions are always welcome!
Post by Denis Bohm
Thanks,
Denis
---------------------------------------------------------------------
Denis Bohm
2003-10-13 18:27:10 UTC
Permalink
Post by Thomas DeWeese
Post by Denis Bohm
I have an application that I would like to implement using SVG and the Java
Language Binding Scripting. I have an SVG document and a Java
EventListenerInitializer that is working in Squiggle. So far, so good.
Now
Post by Thomas DeWeese
Post by Denis Bohm
I would like to sping off a thread that creates a socket connection and
listens for data. When the data arrives I would like to update the SVG DOM.
To do that I need to ask the Batik canvas for the update manager and ask
that for the runnable queue then queue up a runnable to do the update.
However, I don't have a reference to the canvas. Is there some way to get
one from the document?
Well the Window object we provide has a method 'getBridgeContext' and
the BridgeContext can provide you with the UpdateManager (if there is one).
I can't seem to find a way to get the Window from the SVGDocument in Java.
Thomas DeWeese
2003-10-14 10:44:00 UTC
Permalink
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
I would like to sping off a thread that creates a socket connection and
listens for data. When the data arrives I would like to update the SVG DOM.
To do that I need to ask the Batik canvas for the update manager and ask
that for the runnable queue then queue up a runnable to do the update.
However, I don't have a reference to the canvas. Is there some way to
get one from the document?
Well the Window object we provide has a method 'getBridgeContext' and
the BridgeContext can provide you with the UpdateManager (if there is one).
I can't seem to find a way to get the Window from the SVGDocument in Java.
This does appear to be a hole in the current Java binding, as I had
suggested I think this area of the specification is under review.

In Batik there is a method called 'getSVGContext' that you could
call on the DOM nodes this returns one of the Bridges, and they
all have a '.ctx' member that is the BridgeContext. But this is
all _very_ non-standard (I'm also not sure if all the needed methods
and members are public).
Christophe Jolif
2003-10-14 10:48:45 UTC
Permalink
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Well the Window object we provide has a method 'getBridgeContext' and
the BridgeContext can provide you with the UpdateManager (if there is one).
I can't seem to find a way to get the Window from the SVGDocument in Java.
This does appear to be a hole in the current Java binding, as I had
suggested I think this area of the specification is under review.
http://www.w3.org/TR/SVG12/#WindowObject

"A method will be added to the SVGDocument interface to enable access to the
SVGWindow interface."

So Thomas is right, this method will be aded.
--
Christophe
Thomas DeWeese
2003-10-01 09:38:53 UTC
Permalink
Hi Denis.

It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.

If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to reload I
just get a blank page, on the second try to reload it seems to work. But
java.lang.IllegalStateException: RunnableQueue not started or has exited
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the document?
Is that what you are referring to when you say "don't load new SVG documents
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 17:49:43 UTC
Permalink
Hi Thomas,

My animation timer doesn't cache anything (including the runnable queue) -
it get's it from the canvas each time an animation is activated. So it
appears that during a reload a canvas can have a runnable queue still
around - but one that has exited? I don't think I understand which canvas
objects are shutdown, recreated, etc and the timing of all that. I'll take
a look at the Batik source in those areas...

Thanks,
Denis

----- Original Message -----
From: "Thomas DeWeese" <***@Kodak.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 2:38 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Hi Denis.
It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.
If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to reload I
just get a blank page, on the second try to reload it seems to work.
But
Post by Thomas DeWeese
Post by Denis Bohm
java.lang.IllegalStateException: RunnableQueue not started or has exited
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
Post by Thomas DeWeese
Post by Denis Bohm
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the document?
Is that what you are referring to when you say "don't load new SVG documents
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Thomas DeWeese
2003-10-01 18:01:18 UTC
Permalink
Post by Denis Bohm
Hi Thomas,
My animation timer doesn't cache anything (including the runnable queue) -
it get's it from the canvas each time an animation is activated. So it
appears that during a reload a canvas can have a runnable queue still
around - but one that has exited? I don't think I understand which canvas
objects are shutdown, recreated, etc and the timing of all that. I'll take
a look at the Batik source in those areas...
Yes during document loading there is a time where the UpdateManager from
the previous document is still available but shut down, and the UpdateManager
from the new document has yet to be installed.

The UpdateManager does have a 'isRunning()' member, however I would strongly
suggest shutting down your animation engine while a document is being loaded.
From the time you call setDocument/URI to the completion of the first GVT rendering
you should really just leave the canvas alone! :)
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:38 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Hi Denis.
It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.
If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to
reload I
Post by Thomas DeWeese
Post by Denis Bohm
just get a blank page, on the second try to reload it seems to work.
But
Post by Thomas DeWeese
Post by Denis Bohm
java.lang.IllegalStateException: RunnableQueue not started or has exited
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
Post by Thomas DeWeese
Post by Denis Bohm
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the
document?
Post by Thomas DeWeese
Post by Denis Bohm
Is that what you are referring to when you say "don't load new SVG
documents
Post by Thomas DeWeese
Post by Denis Bohm
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 18:18:09 UTC
Permalink
Hi Thomas,

I shut down my animation timer and I no longer see the exception. I still
have to reload twice to get the document to appear. I'm doing:

animationTimer_.shutdown(); // and waits for thread to stop
canvas_.setSVGDocument(null);
// create a new document
canvas_.setSVGDocument(newDocument);

Do you see any problem with that?

Thanks,
Denis

----- Original Message -----
From: "Thomas DeWeese" <***@Kodak.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 11:01 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Post by Denis Bohm
Hi Thomas,
My animation timer doesn't cache anything (including the runnable queue) -
it get's it from the canvas each time an animation is activated. So it
appears that during a reload a canvas can have a runnable queue still
around - but one that has exited? I don't think I understand which canvas
objects are shutdown, recreated, etc and the timing of all that. I'll take
a look at the Batik source in those areas...
Yes during document loading there is a time where the UpdateManager from
the previous document is still available but shut down, and the UpdateManager
from the new document has yet to be installed.
The UpdateManager does have a 'isRunning()' member, however I would strongly
suggest shutting down your animation engine while a document is being loaded.
From the time you call setDocument/URI to the completion of the first GVT rendering
you should really just leave the canvas alone! :)
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:38 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Hi Denis.
It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.
If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to
reload I
Post by Thomas DeWeese
Post by Denis Bohm
just get a blank page, on the second try to reload it seems to work.
But
Post by Thomas DeWeese
Post by Denis Bohm
java.lang.IllegalStateException: RunnableQueue not started or has exited
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the
document?
Post by Thomas DeWeese
Post by Denis Bohm
Is that what you are referring to when you say "don't load new SVG
documents
Post by Thomas DeWeese
Post by Denis Bohm
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Thomas DeWeese
2003-10-01 18:34:32 UTC
Permalink
Post by Denis Bohm
I shut down my animation timer and I no longer see the exception. I still
animationTimer_.shutdown(); // and waits for thread to stop
canvas_.setSVGDocument(null);
// create a new document
canvas_.setSVGDocument(newDocument);
Do you see any problem with that?
Yes (and this is something I've been meaning to fix but haven't).
When you call setSVGDocument(null), it start the processes of 'shutting down'
the current document (canceling repaints, stopping scripts etc), Since
this could take a while I call a number of quick methods to tell everything
to shut down and register a number of event listeners and just return.

When the event listeners are called (because the document is shut down)
I call 'install document' with the document to be installed.

The above code will in most cases register these listeners twice - once for
the 'install' of the null document, once for the install of 'newDocument'. This
probably isn't fatal but as you seem to have discovered don't have a strong notion
of which document (null or new) will in the end be installed.

I would suggest skipping the setSVGDocument(null).

Now that this is likely a 'real problem' as opposed to a theoretical one I
will bump the priority on fixing this issue.
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 11:01 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Post by Denis Bohm
Hi Thomas,
My animation timer doesn't cache anything (including the runnable
queue) -
Post by Thomas DeWeese
Post by Denis Bohm
it get's it from the canvas each time an animation is activated. So it
appears that during a reload a canvas can have a runnable queue still
around - but one that has exited? I don't think I understand which
canvas
Post by Thomas DeWeese
Post by Denis Bohm
objects are shutdown, recreated, etc and the timing of all that. I'll
take
Post by Thomas DeWeese
Post by Denis Bohm
a look at the Batik source in those areas...
Yes during document loading there is a time where the UpdateManager
from
Post by Thomas DeWeese
the previous document is still available but shut down, and the
UpdateManager
Post by Thomas DeWeese
from the new document has yet to be installed.
The UpdateManager does have a 'isRunning()' member, however I would
strongly
Post by Thomas DeWeese
suggest shutting down your animation engine while a document is being
loaded.
Post by Thomas DeWeese
From the time you call setDocument/URI to the completion of the first GVT
rendering
Post by Thomas DeWeese
you should really just leave the canvas alone! :)
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:38 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Hi Denis.
It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.
If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to
reload I
Post by Thomas DeWeese
Post by Denis Bohm
just get a blank page, on the second try to reload it seems to work.
But
Post by Thomas DeWeese
Post by Denis Bohm
java.lang.IllegalStateException: RunnableQueue not started or has
exited
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the
document?
Post by Thomas DeWeese
Post by Denis Bohm
Is that what you are referring to when you say "don't load new SVG
documents
Post by Thomas DeWeese
Post by Denis Bohm
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 18:49:59 UTC
Permalink
That did it! Thanks!

----- Original Message -----
From: "Thomas DeWeese" <***@Kodak.com>
To: "Batik Users" <batik-***@xml.apache.org>
Sent: Wednesday, October 01, 2003 11:34 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Post by Denis Bohm
I shut down my animation timer and I no longer see the exception. I still
animationTimer_.shutdown(); // and waits for thread to stop
canvas_.setSVGDocument(null);
// create a new document
canvas_.setSVGDocument(newDocument);
Do you see any problem with that?
Yes (and this is something I've been meaning to fix but haven't).
When you call setSVGDocument(null), it start the processes of 'shutting down'
the current document (canceling repaints, stopping scripts etc), Since
this could take a while I call a number of quick methods to tell everything
to shut down and register a number of event listeners and just return.
When the event listeners are called (because the document is shut down)
I call 'install document' with the document to be installed.
The above code will in most cases register these listeners twice - once for
the 'install' of the null document, once for the install of 'newDocument'.
This
Post by Thomas DeWeese
probably isn't fatal but as you seem to have discovered don't have a strong notion
of which document (null or new) will in the end be installed.
I would suggest skipping the setSVGDocument(null).
Now that this is likely a 'real problem' as opposed to a theoretical one I
will bump the priority on fixing this issue.
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 11:01 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading issue
Post by Thomas DeWeese
Post by Denis Bohm
Hi Thomas,
My animation timer doesn't cache anything (including the runnable
queue) -
Post by Thomas DeWeese
Post by Denis Bohm
it get's it from the canvas each time an animation is activated. So it
appears that during a reload a canvas can have a runnable queue still
around - but one that has exited? I don't think I understand which
canvas
Post by Thomas DeWeese
Post by Denis Bohm
objects are shutdown, recreated, etc and the timing of all that. I'll
take
Post by Thomas DeWeese
Post by Denis Bohm
a look at the Batik source in those areas...
Yes during document loading there is a time where the UpdateManager
from
Post by Thomas DeWeese
the previous document is still available but shut down, and the
UpdateManager
Post by Thomas DeWeese
from the new document has yet to be installed.
The UpdateManager does have a 'isRunning()' member, however I would
strongly
Post by Thomas DeWeese
suggest shutting down your animation engine while a document is being
loaded.
Post by Thomas DeWeese
From the time you call setDocument/URI to the completion of the first GVT
rendering
Post by Thomas DeWeese
you should really just leave the canvas alone! :)
Post by Denis Bohm
Thanks,
Denis
----- Original Message -----
Sent: Wednesday, October 01, 2003 2:38 AM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Hi Denis.
It looks to me like you need to shut down your
SVGStage.AnimationTimer before you 'unload' the current
document (or load a new document). Since this class appears
to be 'outside' of Batik there is no way for us to shut it
down for you.
If it is really on a Java Timer I believe you can cancel
them.
Post by Denis Bohm
I'm having a problem reloading a document. The first time I try to
reload I
Post by Thomas DeWeese
Post by Denis Bohm
just get a blank page, on the second try to reload it seems to work.
But
Post by Thomas DeWeese
Post by Denis Bohm
java.lang.IllegalStateException: RunnableQueue not started or has
exited
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
at
org.apache.batik.util.RunnableQueue.invokeAndWait(RunnableQueue.java:257)
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
Post by Thomas DeWeese
Post by Denis Bohm
at
com.fireflydesign.svg.SVGStage$AnimationTimer.run(SVGStage.java:639)
and things don't function anymore.
I assume that I need to shut somethings down before changing the
document?
Post by Thomas DeWeese
Post by Denis Bohm
Is that what you are referring to when you say "don't load new SVG
documents
Post by Thomas DeWeese
Post by Denis Bohm
until pending DOM updates"?
Thanks,
Denis
----- Original Message -----
Sent: Monday, September 29, 2003 12:29 PM
Subject: Re: JSVGComponent dynamic DOM update, invokeAndWait threading
issue
Post by Thomas DeWeese
Post by Denis Bohm
Post by George Armhold
Sorry for the late reply to this thread; I was travelling when your
reply came in.
Post by George Armhold
So now my question is: how can I know when it's safe to call
UpdateManager um = getUpdateManager();
RunnableQueue rq = um.getUpdateRunnableQueue();
and add things to the RunnableQueue?
It is safe after the first GVT rendering completes. This is
_before_ the managerStarted call back, so this shouldn't be the
problem. You should have enough instrumentation in your code now to
figure out what the sequence of events is that leads to the Null
UpdateManager is.
Indeed, thanks to your help. It seems there were two key issues in my
- make sure sure UpdateManager is available (wait until
gvtRenderingCompleted event) before starting DOM updates.
- don't load new SVG documents until pending DOM updates
(UpdateManager's RunnableQueue) to the currently loaded doc have
completed.
Although I need to complete more testing, I have not seen any more
crashes since applying these two fixes. Thanks!
--
George Armhold
Rutgers University
eLearning Grant, DCIS
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
Denis Bohm
2003-10-01 18:55:23 UTC
Permalink
Can Batik be run as an Internet Explorer Plugin? In the same way as the
Adobe SVG Viewer?
Thomas DeWeese
2003-10-01 19:28:54 UTC
Permalink
Post by Denis Bohm
Can Batik be run as an Internet Explorer Plugin? In the same way as the
Adobe SVG Viewer?
Not that I am aware of. Some people have played with using Batik
as an applet. You can also start it from a web page using Java Web Start,
but AFAIK you can't use java to handle a particular mime type in IE,
apparently this _is_ possible in Mozilla (I think they were/are called
pluglets) this was done for a _very_ early version of Batik but I
don't know where that code is (I don't think it was ever actually
contributed- and it probably wouldn't be all that useful at this point).
Vincent Hardy
2003-10-02 07:15:24 UTC
Permalink
Post by Thomas DeWeese
Post by Denis Bohm
Can Batik be run as an Internet Explorer Plugin? In the same way as the
Adobe SVG Viewer?
Not that I am aware of. Some people have played with using Batik
as an applet. You can also start it from a web page using Java Web Start,
but AFAIK you can't use java to handle a particular mime type in IE,
apparently this _is_ possible in Mozilla (I think they were/are called
pluglets) this was done for a _very_ early version of Batik but I
don't know where that code is (I don't think it was ever actually
contributed- and it probably wouldn't be all that useful at this point).
Thomas,

Your recollection is correct: we did a proof of concept using a Mozilla
project called Blackwood. This was over two years ago. See:

http://www.mozilla.org/projects/blackwood/overview.html

Vincent.
George Armhold
2003-10-08 17:59:56 UTC
Permalink
I'm still struggling with threads in Batik. A previously discussed
recommendation was to "leave the canvas alone until
gvtTreeRenderingComplete is fired". However what does one do when the
requests for updating the canvas/DOM are firing from the Swing thread?
You can't block in the Swing thread, because the Batik events are
apparently fired from there as well, so I'll never see
gvtTreeRenderingComplete. Here's the scenario:

1. Swing event triggers canvas.setSVGDocument(firstDoc).

2. manipulate firstDoc's DOM (in UpdateManger's thread) in response to
Swing mouse clicks, etc.

3. Swing event calls canvas.getSVGDocument() to get the modified
firstDoc back, and then canvas.setSVGDocument(secondDoc).

4. manipulate firstDoc's DOM in Swing thread.

I then get a NullPointerException, presumably because I am modifying
the firstDoc DOM outside of the UpdateManager thread. The kind of
situation that is triggering this behavior is when the user clicks the
"load next SVG document" button too quickly in succession.

Perhaps I am going about things the wrong way, because very often when
using the canvas I end up trying all sorts of threading chicanery to
simulate blocking for Batik's non-blocking methods.

Thanks
Thomas DeWeese
2003-10-08 18:33:37 UTC
Permalink
Post by George Armhold
I'm still struggling with threads in Batik. A previously discussed
recommendation was to "leave the canvas alone until
gvtTreeRenderingComplete is fired". However what does one do when the
requests for updating the canvas/DOM are firing from the Swing thread?
You can't block in the Swing thread, because the Batik events are
apparently fired from there as well, so I'll never see
1. Swing event triggers canvas.setSVGDocument(firstDoc).
2. manipulate firstDoc's DOM (in UpdateManger's thread) in response to
Swing mouse clicks, etc.
3. Swing event calls canvas.getSVGDocument() to get the modified
firstDoc back, and then canvas.setSVGDocument(secondDoc).
Hi George,

So are we OK up to here?
Post by George Armhold
4. manipulate firstDoc's DOM in Swing thread.
I then get a NullPointerException, presumably because I am modifying
the firstDoc DOM outside of the UpdateManager thread.
Well a stack trace would have helped to identify why you get
the NPE. But my assumption is that you are modifying the firstDoc
before the UpdateManager that has been managing it is shut down.
There is a set of UpdateManagerEvents that you can listen to, in order
to know when it has shut down.
Post by George Armhold
The kind of
situation that is triggering this behavior is when the user clicks the
"load next SVG document" button too quickly in succession.
It isn't clear to me why you are modifying the firstDoc's DOM
when it isn't being displayed or why going to the next SVG Document would
cause problems with 'previous' documents.
Post by George Armhold
Perhaps I am going about things the wrong way, because very often when
using the canvas I end up trying all sorts of threading chicanery to
simulate blocking for Batik's non-blocking methods.
Well it sounds to me like you need to queue these user events until
the system can catch up with them. I would suggest using something
like our RunnableQueue to do this. This way the Swing thread can construct
a runnable to 'load the next document' and stick it in the runnable queue.
The first thing the runnable does is check that the canvas is 'stable' (Which
can block because we are out of the Swing thread) then it can install the
next document. If the user has pressed 'load the next document' four times
in between you can either let the user wait for the 'intermediate' pages to
stop/start/stop/start or do a sort of 'event compression' where you
remove the earlier load events from the RunnableQueue (this is done for mouse
events in Batik).
Post by George Armhold
Thanks
---------------------------------------------------------------------
George Armhold
2003-10-08 20:23:38 UTC
Permalink
Post by Thomas DeWeese
Post by George Armhold
1. Swing event triggers canvas.setSVGDocument(firstDoc).
2. manipulate firstDoc's DOM (in UpdateManger's thread) in response to
Swing mouse clicks, etc.
3. Swing event calls canvas.getSVGDocument() to get the modified
firstDoc back, and then canvas.setSVGDocument(secondDoc).
Hi George,
So are we OK up to here?
Yes.
Post by Thomas DeWeese
Well a stack trace would have helped to identify why you get the
NPE. But my assumption is that you are modifying the firstDoc
before the UpdateManager that has been managing it is shut down.
I agree, it's because I am modifying the DOM outside of the
UpdateManager's thread. Here's a stack trace.

java.lang.NullPointerException
at org.apache.batik.bridge.CSSUtilities.convertDisplay(Unknown Source)
at
org.apache.batik.bridge.AbstractGraphicsNodeBridge.getDisplay(Unknown
Source)
at org.apache.batik.bridge.GVTBuilder.build(Unknown Source)
at org.apache.batik.bridge.SVGGElementBridge.handleElementAdded(Unknown
Source)
at
org.apache.batik.bridge.SVGGElementBridge.handleDOMNodeInsertedEvent(Unknown
Source)
at
org.apache.batik.bridge.BridgeContext$DOMNodeInsertedEventListener.handleEvent(Unknown
Source)
at org.apache.batik.dom.events.EventSupport.fireEventListeners(Unknown
Source)
at org.apache.batik.dom.events.EventSupport.dispatchEvent(Unknown Source)
at org.apache.batik.dom.AbstractNode.dispatchEvent(Unknown Source)
at
org.apache.batik.dom.AbstractParentNode.fireDOMNodeInsertedEvent(Unknown
Source)
at org.apache.batik.dom.AbstractParentNode.appendChild(Unknown Source)
at edu.rutgers.elearning.util.SVGUtils.newScribbleGroup(SVGUtils.java:87)
at
edu.rutgers.elearning.scribble.ScribbleComponent.addScribbleGroup(ScribbleComponent.java:968)
at
edu.rutgers.elearning.presenter.Presenter.saveCurrentSlide(Presenter.java:903)
at
edu.rutgers.elearning.presenter.Presenter.displaySlide(Presenter.java:1020)
at edu.rutgers.elearning.presenter.Presenter.access$400(Presenter.java:79)
at
edu.rutgers.elearning.presenter.Presenter$14.actionPerformed(Presenter.java:617)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1786)
at
javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1839)
at
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at
com.sun.java.swing.plaf.gtk.SynthButtonListener.mouseReleased(SynthButtonListener.java:250)
at java.awt.Component.processMouseEvent(Component.java:5100)
at java.awt.Component.processEvent(Component.java:4897)
at java.awt.Container.processEvent(Container.java:1569)
at java.awt.Component.dispatchEventImpl(Component.java:3615)
at java.awt.Container.dispatchEventImpl(Container.java:1627)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3198)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
at java.awt.Container.dispatchEventImpl(Container.java:1613)
at java.awt.Window.dispatchEventImpl(Window.java:1606)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Post by Thomas DeWeese
There is a set of UpdateManagerEvents that you can listen to, in
order to know when it has shut down.
Which thread are the UpdateManagerEvents fired in? The javadoc
documentation implies that they run in Swing. Which means I'd
deadlock if I blocked waiting for them, since my event is also running
in the Swing thread. Unless I spawned a new thread for each Swing
event, which is kind of a mess.
Post by Thomas DeWeese
It isn't clear to me why you are modifying the firstDoc's DOM when
it isn't being displayed or why going to the next SVG Document would
cause problems with 'previous' documents.
Well I place an SVG doc into the canvas, let the user modify it, and
then unload it (actually, load a new doc.) Then I modify the
(unloaded) doc to adjust some of the settings before saving the XML to
a file. The modifications after unload are just the logic of my app;
nothing that needs to be displayed. The trouble seems to stem from
the fact that I'm not properly waiting for the doc to be "unloaded"
from the canvas.
Post by Thomas DeWeese
Well it sounds to me like you need to queue these user events until
the system can catch up with them. I would suggest using something
like our RunnableQueue to do this.
Yeah, this is what I am afraid of. It would really complicate things
to propagate the "queueness" of the canvas to the rest of our app.
I'm trying to isolate all of the batik event handling to my canvas
extension, and keep it as much a black box as possible. We need
synchronous behavior for the rest of the app (load the doc, modify it,
unload it, install next doc.)
Post by Thomas DeWeese
The first thing the runnable does is check that the canvas is
'stable' (Which can block because we are out of the Swing thread)
then it can install the next document.
Ah, so maybe the UpdateManager's events are not fired from the Swing
thread after all?
Thomas DeWeese
2003-10-08 21:04:08 UTC
Permalink
Post by George Armhold
Post by Thomas DeWeese
Post by George Armhold
1. Swing event triggers canvas.setSVGDocument(firstDoc).
2. manipulate firstDoc's DOM (in UpdateManger's thread) in response to
Swing mouse clicks, etc.
3. Swing event calls canvas.getSVGDocument() to get the modified
firstDoc back, and then canvas.setSVGDocument(secondDoc).
Hi George,
So are we OK up to here?
Yes.
Post by Thomas DeWeese
Well a stack trace would have helped to identify why you get the
NPE. But my assumption is that you are modifying the firstDoc
before the UpdateManager that has been managing it is shut down.
I agree, it's because I am modifying the DOM outside of the
UpdateManager's thread. Here's a stack trace.
java.lang.NullPointerException
at org.apache.batik.bridge.CSSUtilities.convertDisplay(Unknown Source)
at org.apache.batik.bridge.AbstractGraphicsNodeBridge.getDisplay(Unknown Source)
at org.apache.batik.bridge.GVTBuilder.build(Unknown Source)
at org.apache.batik.bridge.SVGGElementBridge.handleElementAdded(Unknown Source)
at org.apache.batik.bridge.SVGGElementBridge.handleDOMNodeInsertedEvent(Unknown Source)
at org.apache.batik.bridge.BridgeContext$DOMNodeInsertedEventListener.handleEvent(Unknown Source)
Hmm you seem to be getting exceedingly unlucky here. :) The NPE is caused
by the BridgeContext dispose method disposing of the CSSEngine (no display
property anymore). But the dispose of the CSSEngine is done _after_ the
BridgeContext DOM listeners are removed from the Document.
Post by George Armhold
Post by Thomas DeWeese
There is a set of UpdateManagerEvents that you can listen to, in
order to know when it has shut down.
Which thread are the UpdateManagerEvents fired in?
The UpdateManager RunnableQueue thread, not Swing, but see below...
Post by George Armhold
Post by Thomas DeWeese
Well it sounds to me like you need to queue these user events until
the system can catch up with them. I would suggest using something
like our RunnableQueue to do this.
Yeah, this is what I am afraid of. It would really complicate things
to propagate the "queueness" of the canvas to the rest of our app.
I'm trying to isolate all of the batik event handling to my canvas
extension, and keep it as much a black box as possible. We need
synchronous behavior for the rest of the app (load the doc, modify it,
unload it, install next doc.)
Well just my 2c but blocking the Swing thread is really bad behavior
for an application. If you want to 'suspend' user interaction that is
fine but don't block the Swing thread.
Post by George Armhold
Post by Thomas DeWeese
The first thing the runnable does is check that the canvas is
'stable' (Which can block because we are out of the Swing thread)
then it can install the next document.
Ah, so maybe the UpdateManager's events are not fired from the Swing
thread after all?
Even if it were called in the Swing thread you can have a small class
that just tracks the 'state' of the Canvas. Heck the modification of the
document to be written can be delayed indefinitely. So when I went to
set the new document I would do something like:

final Document oldDoc = canvas.getSVGDocument();
final UpdateManager um = canavs.getUpdateManager();
um.addUpdateManagerListener(new UpdateManagerAdapter() {
public void managerStopped(UpdateManagerEvent e) {
um.removeUpdateManagerListener(this);
prepDocument(oldDoc);
writeDocument(oldDoc);
}
};
canvas.setSVGDocument(newDoc);

This Listener will 'hang out' until the UpdateManager stops then it will
prep the old doc for write, then write it, no blocking or anything
messy.
Thomas DeWeese
2003-10-08 21:28:21 UTC
Permalink
Post by Thomas DeWeese
Even if it were called in the Swing thread you can have a small class
that just tracks the 'state' of the Canvas. Heck the modification of the
document to be written can be delayed indefinitely. So when I went to
final Document oldDoc = canvas.getSVGDocument();
final UpdateManager um = canavs.getUpdateManager();
um.addUpdateManagerListener(new UpdateManagerAdapter() {
public void managerStopped(UpdateManagerEvent e) {
um.removeUpdateManagerListener(this);
prepDocument(oldDoc);
writeDocument(oldDoc);
}
};
canvas.setSVGDocument(newDoc);
This Listener will 'hang out' until the UpdateManager stops then it will
prep the old doc for write, then write it, no blocking or anything
messy.
Hmm, there is a problem with this. The BridgeContext isn't disposed of
until after all the managerStopped Listeners have been called. I don't think
this is correct behavior, but until it's fixed you will actually have to
hang your listener off the document load or gvt build listener to make
sure the old document is no longer 'active'.
George Armhold
2003-10-08 22:18:42 UTC
Permalink
Hmm you seem to be getting exceedingly unlucky here. :) The NPE is
caused by the BridgeContext dispose method disposing of the
CSSEngine (no display property anymore). But the dispose of the
CSSEngine is done _after_ the BridgeContext DOM listeners are
removed from the Document.
Um, OK. I didn't know that the CSSEngine was something I had to worry
about. I'll add it to the list. ;-)
Well just my 2c but blocking the Swing thread is really bad behavior
for an application.
I agree in principle about not making Swing block. In fact I just
finished code to farm off SVG -> BufferedImage rasterization in a
separate thread, to keep Swing "lively". But I was assuming that the
time it takes to wait for the document unloading to happen was pretty
small.
Heck the modification of the document to be written can be delayed
indefinitely.
Yes and no. There is logic in the rest of our app that expects to get
the "old" document back from the canvas and "do stuff" with it. Of
course we can install callbacks that are fired when the doc is really
unloaded, but our code is quickly turning into a tangled mess of such
callbacks. But if I must, I must. :-)
Post by Thomas DeWeese
final Document oldDoc = canvas.getSVGDocument();
final UpdateManager um = canavs.getUpdateManager();
um.addUpdateManagerListener(new UpdateManagerAdapter() {
public void managerStopped(UpdateManagerEvent e) {
um.removeUpdateManagerListener(this);
prepDocument(oldDoc);
writeDocument(oldDoc);
}
};
canvas.setSVGDocument(newDoc);
Hmm, there is a problem with this. The BridgeContext isn't disposed
of until after all the managerStopped Listeners have been called. I
don't think this is correct behavior, but until it's fixed you will
actually have to hang your listener off the document load or gvt
build listener to make sure the old document is no longer 'active'.
You mean I should install this listener after (say) gvtBuildCompleted?

Thanks as always for your wisdom!
Thomas DeWeese
2003-10-09 09:30:40 UTC
Permalink
Post by George Armhold
Yes and no. There is logic in the rest of our app that expects to get
the "old" document back from the canvas and "do stuff" with it. Of
course we can install callbacks that are fired when the doc is really
unloaded, but our code is quickly turning into a tangled mess of such
callbacks. But if I must, I must. :-)
This tends to be the nature of GUI programs, they can almost never
be implemented as clean procedural code.
Post by George Armhold
Post by Thomas DeWeese
Post by Thomas DeWeese
final Document oldDoc = canvas.getSVGDocument();
final UpdateManager um = canavs.getUpdateManager();
um.addUpdateManagerListener(new UpdateManagerAdapter() {
public void managerStopped(UpdateManagerEvent e) {
um.removeUpdateManagerListener(this);
prepDocument(oldDoc);
writeDocument(oldDoc);
}
};
canvas.setSVGDocument(newDoc);
Hmm, there is a problem with this. The BridgeContext isn't disposed
of until after all the managerStopped Listeners have been called. I
don't think this is correct behavior, but until it's fixed you will
actually have to hang your listener off the document load or gvt
build listener to make sure the old document is no longer 'active'.
You mean I should install this listener after (say) gvtBuildCompleted?
No I meant you will need to use the gvtBuildCompleted event to
know that your oldDoc is 100% disentangled from the Canvas. You should
probably also catch the build failed (problem with doc), and build canceled events
as well.
George Armhold
2003-10-10 08:12:56 UTC
Permalink
Post by Thomas DeWeese
Hmm, there is a problem with this. The BridgeContext isn't disposed
of until after all the managerStopped Listeners have been called. I
don't think this is correct behavior, but until it's fixed you will
actually have to hang your listener off the document load or gvt
build listener to make sure the old document is no longer 'active'.
Post by George Armhold
You mean I should install this listener after (say) gvtBuildCompleted?
No I meant you will need to use the gvtBuildCompleted event to know
that your oldDoc is 100% disentangled from the Canvas. You should
probably also catch the build failed (problem with doc), and build
canceled events as well.
Sorry, but I don't quite understand how waiting for gvtBuildCompleted
fixes the problem with the BridgeContext. Won't
gvtBuildCompleted/Canceled/Failed get called way before the
UpdateManagerListeners? I can see how it makes sense to catch these
events in case the UpdateManager never gets started (I'm assuming it
won't be started if the gvtBuild gets canceled/failed.) And from
previous discussion I think I also need to wait until
gvtRenderingCompleted before even getting access to the UpdateManager.
So my understanding (probably incorrect) is that I need to do the
following to know when the canvas is "done" with the document:

If I see any of:

documentLoadingCanceled
documentLoadingFailed
gvtBuildCanceled
gvtBuildFailed
gvtRenderingCanceled
gvtRenderingFailed

then there was a problem, and the UpdateManager never got started.
Else, when I wait for gvtRenderingCompleted, at which point I can
safely call getUpdateManager, and then wait for managerStopped. THEN
it's safe to access the document. Whew. :-) I am basing this on the
"Rendering Process" section of the JSVGComponent javadoc. Where am I
going wrong?

Thanks!
Thomas DeWeese
2003-10-10 11:43:20 UTC
Permalink
Post by George Armhold
Post by Thomas DeWeese
Hmm, there is a problem with this. The BridgeContext isn't disposed
of until after all the managerStopped Listeners have been called. I
don't think this is correct behavior, but until it's fixed you will
actually have to hang your listener off the document load or gvt
build listener to make sure the old document is no longer 'active'.
Post by George Armhold
You mean I should install this listener after (say) gvtBuildCompleted?
No I meant you will need to use the gvtBuildCompleted event to know
that your oldDoc is 100% disentangled from the Canvas. You should
probably also catch the build failed (problem with doc), and build
canceled events as well.
Sorry, but I don't quite understand how waiting for gvtBuildCompleted
fixes the problem with the BridgeContext.
I should have said gvtBuildStarted (although completed would work it's
later than it needs to be). The problem is that the BridgeContext
isn't disposed of (which completes the disentanglement) until shorty
_after_ all the UpdateManagerStopped events are delivered. So what I
am suggesting is waiting for the first event after UpdateManagerStopped so
you know that the Canvas has disposed of the BridgeContext for the previous
document.

I will probably fix this problem with BridgeContext disposal shortly
(over the weekend) so you could just wait for that (I think
UpdateManagerStopped should signal that the Canvas is done with the document).
George Armhold
2003-10-10 14:42:32 UTC
Permalink
Post by Thomas DeWeese
I will probably fix this problem with BridgeContext disposal shortly
(over the weekend) so you could just wait for that (I think
UpdateManagerStopped should signal that the Canvas is done with the document).
That works for me. Thanks again, Thomas!
George Armhold
2003-10-11 14:49:19 UTC
Permalink
Is it safe to call setSVGDocument at any time, or must I make sure
that the previous doc loading/building/rendering has completed? I
just constructed a test case that loads several documents in
succession, and get the following NPE:

java.lang.NullPointerException
at org.apache.batik.swing.svg.JSVGComponent.stopThenRun(Unknown
Source)
at
org.apache.batik.swing.svg.JSVGComponent.setSVGDocument(Unknown Source)
at CanvasTest$1.run(CanvasTest.java:63)
at org.apache.batik.util.RunnableQueue.run(Unknown Source)
at java.lang.Thread.run(Thread.java:534)


I was assuming that the "canceled" methods in the various listener
interfaces meant that the canvas correctly handles requests to load
new docs before in-progress loads have completed.

Thanks
--
George Armhold
Rutgers University
eLearning Grant, DCIS
Thomas DeWeese
2003-10-12 12:25:43 UTC
Permalink
Post by George Armhold
Is it safe to call setSVGDocument at any time, or must I make sure
that the previous doc loading/building/rendering has completed? I
just constructed a test case that loads several documents in
It is safe to call 'setSVGDocument' at any time - but as with all
Swing components you should only call methods from the Swing thread.
We have a pretty good test of this in regard (our test harness) so I'm
fairly confident that it works properly. In the case below you should
be able to do an EventQueue.invokeAndWait(...).
Post by George Armhold
java.lang.NullPointerException
at org.apache.batik.swing.svg.JSVGComponent.stopThenRun(Unknown
Source)
at
org.apache.batik.swing.svg.JSVGComponent.setSVGDocument(Unknown Source)
at CanvasTest$1.run(CanvasTest.java:63)
at org.apache.batik.util.RunnableQueue.run(Unknown Source)
at java.lang.Thread.run(Thread.java:534)
I was assuming that the "canceled" methods in the various listener
interfaces meant that the canvas correctly handles requests to load
new docs before in-progress loads have completed.
Thanks
Loading...