This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 45 - Pages: 4 [ 1 2 3 4 | Next ] - Last Post: 21 Jul 21, 22:53 Last Post By: xexyl Threads: [ Previous | Next ]
ctwist

Posts: 471
Registered: 27-Sep-2003
Changed filter processing in 23.0.1
Posted: 15 Feb 21, 18:41
 
  Click to reply to this thread Reply
This message relates to a user's complaint that frames are no longer created in BluPlusPlus https://jalbum.net/forum/thread.jspa?threadID=56867. Yes BPP is a dinosaur, but this problem could affect other skins.

Starting in jAlbum 23.0.1, filter processing has changed.

BPPFrameHandler has 2 constructors. I added a stack dump to each of these, so that I could determine when it is called.

My test project contains two images. I did a Force Remake in jAlbum 23 and 23.2. The console output is attached.

I compared the two console outputs.
  • The first 242 lines are identical, except for minor changes to line numbers.
  • jAlbum 23.2 then reports 4 additional calls to the first constructor. Each of these failed.

It seems that jAlbum 23 allowed BPP to do its own filter processing, but 23.2 tries to trigger the filter processing itself.

So:
  • Why was filter processing changed in jAlbum 23.0.1?
  • Should BPP be changed to conform to the new technique, or is jAlbum misbehaving?
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: Changed filter processing in 23.0.1
Posted: 16 Feb 21, 20:06   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
Chris, ensure that the filter has both a default, no args constructor and both getter and setter methods. The change made since v23.1 is that we now make a clone of the filter for each execution thread. For the cloning to work, there needs to be a no-args constructor and getter and setter methods corresponding to the JavaBeans spec.

The cloning is done to ensure that filters that contain state won't bug things when executed over multiple threads. Prior to v23 we used one single filter instance and synchronized the filter call, but this doesn't scale well when users have multiple CPU cores. v23 removed the synchronization and gained performance, but broke XBorderFilter (that contains state). v23.1 solved this by cloning filters for each execution thread.

The only side effect of this change I can imagine now (apart from filters needing to follow the JavaBean spec with regards to no-args constructor and getter/setter methods) is that no state is kept BETWEEN each filter() invocation (a new clone is used every time)

Edited by: davidekholm on 16-Feb-2021 20:06
ctwist

Posts: 471
Registered: 27-Sep-2003
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 04:31   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
There is a no args constructor in BppFrameHandler. There are methods getName(), getDescription(). I don't know what else is needed.

A NullPointerException was occurring at CompiledBase.java:57 (i.e. engine was null) because the no args constructor did not assign a value to engine. I fixed this in the constructor by setting engine to JAlbumContext.getInstance().getEngine(). However this was not a solution; "applylevel" also needs to be set, and this is only set in the constructor that accepts arguments. Consequently frames are not added.

I don't understand how BppFrameHandler should be restructured to add frames. I don't understand what should be in the no args constructor (previously it was empty).

Is a template filter available that conforms to the new structure? Is there any documentation about how to do this? I couldn't find anything. The sample filter source code does not have constructors, so it is not helpful.

Maybe BluPlusPlus uses a proprietary technique for applying filters?

Time to go and listen to some Led Zeppelin. Maybe "Dazed and Confused" would be appropriate.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 12:20   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
Hi Chris,

The sample filter doesn't have any explicit constructor at all, that means that a no-args constructor is added implicitly by Java, but as soon as one adds one explicit constructor, the implicit no-args constructor is no longer added. To add one manually, simpy write public BppFrameHandler() {}

All filters under "plugins" work with the new scheme.
JeffTucker

Posts: 8,037
Registered: 31-Jan-2006
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 12:26   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
The other option is to decide that BPP should be moved to the legacy skins section, and just move on. Is this really worth the tsuris?
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 12:29   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Chris, the code fails cause your BPPFrameHandler filter doens't follow the JavaBean specification. The full state of an instance of this class needs to be replicated by cloning the instance by calling getter and setter methods. Each class member variable needs a pair of getters and setters. Add the following to your source code and it should work:
    public Map<String, BPPFilterGroup> getFilterGroupMap() {
        return filterGroupMap;
    }
 
    public void setFilterGroupMap(Map<String, BPPFilterGroup> filterGroupMap) {
        this.filterGroupMap = filterGroupMap;
    }
 
    public int getApplyLevel() {
        return applyLevel;
    }
 
    public void setApplyLevel(int applyLevel) {
        this.applyLevel = applyLevel;
    }
 
    public int getApplyRatio() {
        return applyRatio;
    }
 
    public void setApplyRatio(int applyRatio) {
        this.applyRatio = applyRatio;
    }
 
    public File getConfigDir() {
        return configDir;
    }
 
    public void setConfigDir(File configDir) {
        this.configDir = configDir;
    }
 
    public AlbumBean getEngine() {
        return engine;
    }
 
    public void setEngine(AlbumBean engine) {
        this.engine = engine;
    }
 
    public Base getBase() {
        return base;
    }
 
    public void setBase(Base base) {
        this.base = base;
    }
 
    public File getSkinDirectory() {
        return skinDirectory;
    }
 
    public void setSkinDirectory(File skinDirectory) {
        this.skinDirectory = skinDirectory;
    }


Now that's a lot of code, but it's also how the JavaBean spec looks. Future Java versions will have shorter syntax for such simple getters/setters. Note, jAlbum has always documented requirement to follow this specification, but it's perhaps only with v23.1 that things break if your don't.

As it's so laborious to manually write these getters and setters, Netbeans automates it for you if you keep the cursor on the line where a class member variable is declared and then hit CTRL+I and select "getter and setter" from the popup menu. That's how I had this code generated.
ctwist

Posts: 471
Registered: 27-Sep-2003
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 15:09   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
JeffTucker wrote:
The other option is to decide that BPP should be moved to the legacy skins section, and just move on. Is this really worth the tsuris?
I assumed that there is a simple fix, so I thought that it was worth spending some time fixing this. The knowledge learned could also help with other skins.
ctwist

Posts: 471
Registered: 27-Sep-2003
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 15:23   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
I saw your instruction to add "getter and setter methods corresponding to the JavaBeans spec" but I didn't know what that meant.

I use Eclipse. I checked the menus and found an option "Source / Generate getters and setters". I chose this and now the code is updated.

Now it is time to test.
JeffTucker

Posts: 8,037
Registered: 31-Jan-2006
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 15:30   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
ctwist wrote:
Now it is time to test.

Oh, you don't want to do that!

That's just the trail to heartbreak.
ctwist

Posts: 471
Registered: 27-Sep-2003
Re: Changed filter processing in 23.0.1
Posted: 17 Feb 21, 17:10   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
I tested the updated class with the additional getters and setters. I tested in 23.2 and 23.0.0. In both cases it failed with the same errors. These are the errors in 23.2
An unexpected error occurred. Please see detailed description below:
 
java.lang.RuntimeException: java.io.IOException: java.io.IOException: java.io.IOException: java.lang.NullPointerException
	at se.datadosen.jalbum.AlbumBean.getImageSettingsHash(AlbumBean.java:916)
	at se.datadosen.jalbum.AlbumBean.makeAlbum(AlbumBean.java:2874)
	at se.datadosen.jalbum.AlbumBean.makeAlbum(AlbumBean.java:2823)
	at se.datadosen.jalbum.JAlbumFrame$6.run(JAlbumFrame.java:1128)
Caused by: java.io.IOException: java.io.IOException: java.io.IOException: java.lang.NullPointerException
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:89)
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:61)
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:52)
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:24)
	at se.datadosen.jalbum.AlbumBean.getImageSettingsHash(AlbumBean.java:914)
	... 3 more
Caused by: java.io.IOException: java.io.IOException: java.lang.NullPointerException
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:89)
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:80)
	... 7 more
Caused by: java.io.IOException: java.lang.NullPointerException
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:89)
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:80)
	... 8 more
Caused by: java.lang.NullPointerException
	at se.datadosen.jalbum.JSONEncoder.serialize(JSONEncoder.java:74)
	... 9 more
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: Changed filter processing in 23.0.1
Posted: 18 Feb 21, 15:11   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
Chris, that error is caused by some class member variables being null sometimes. It's the code that generates an image settings hash that bails out due to this. We use the image settings hash to intelligently figure out whether an image needs to be reprocessed or not. The hash is stored with each generated image. Now, I could fix the null thing, but it just moves the problem one step ahead: Now it will serialize the full AlbumBean (if it's not null), i.e all properties of it, and we don't want that cause there are many properties that aren't image specific, yet, when included in the hashing will trigger re-generation of images when changed.

The best approach forward is to rewrite BPPFrameHandler so it doesn't contain any state that isn't pure image-specific properties (that can be easily serialized and then hashed). You should be able to gather all needed objects, like "engine" via the "vars" argument of the filter() method. If you find yourself needing to pass around several objects, like "engine" between methods, create an instance of class that's created upon the filter() call that contains the needed objects, but don't keep this instance as a class level variable (so it's kept out of the serialization)
ctwist

Posts: 471
Registered: 27-Sep-2003
Re: Changed filter processing in 23.0.1
Posted: 18 Feb 21, 21:03   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
I have given up on this.

BPPFilterGroup also implements JAFilter. It is in a hierarchy that has CompiledBase at the top; which doesn't have a no-args constructor.

Untangling all this would take time and require a complete re-test.

Anybody who uses BPP will have to install jAlbum 23.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: Changed filter processing in 23.0.1
Posted: 18 Feb 21, 21:20   in response to: ctwist in response to: ctwist
 
  Click to reply to this thread Reply
Understandable
xexyl

Posts: 157
Registered: 1-Sep-2009
Re: Changed filter processing in 23.0.1
Posted: 18 Jul 21, 15:24   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Well my skin which has several filters (some of which are quite complex when it comes to options) is now broken too. See below for my comments (I'll possibly reply to other comments too).

Note that I don't have any errors in the log. I also already have a no-args constructor. I also have getters and setters but I don't known if they're all used. Is this required? For example do I have to use a getter every time I refer to a variable in the class? That seems silly to me and would make the code even uglier yet looking at it I think I do do that at least in the one filter I am testing (the others I know don't work but I am pretty sure I also use setters and getters).

davidekholm wrote:
Chris, ensure that the filter has both a default, no args constructor and both getter and setter methods. The change made since v23.1 is that we now make a clone of the filter for each execution thread. For the cloning to work, there needs to be a no-args constructor and getter and setter methods corresponding to the JavaBeans spec.

Well as I said my ReflectionFilter does have getters and setters and a no args constructor and it's not working correctly (it does filter images but it's really weird and definitely wrong). Now I can upload it here or in a different post if you wan though I warn you it's kind of big and it does refer to another filter or maybe two that are much more complicated (well one is much more complicated) and I don't think you'd want to look at them anyway.

The cloning is done to ensure that filters that contain state won't bug things when executed over multiple threads. Prior to v23 we used one single filter instance and synchronized the filter call, but this doesn't scale well when users have multiple CPU cores. v23 removed the synchronization and gained performance, but broke XBorderFilter (that contains state). v23.1 solved this by cloning filters for each execution thread.

Would you please implement a feature that this will work on single threads? Because as you can see it's not only Chris's filter that is broken; I have several that are broken and I imagine there are others that are also broken. I find it very annoying and all the more since I also just updated my subscription when now it seems useless and pointless to even have the option of updating jAlbum; it's as if I spent the money for no reason.

Additionally I already do have getters/setters and no arg constructor and unless I'm doing something wrong (and I wasn't doing anything wrong before!) I don't see what else I'm supposed to do. Frustratingly you don't seem to have the documentation updated as Chris pointed out. That's not good.

The only side effect of this change I can imagine now (apart from filters needing to follow the JavaBean spec with regards to no-args constructor and getter/setter methods) is that no state is kept BETWEEN each filter() invocation (a new clone is used every time)

I'm too tired to tell right now but this might actually affect one of my filters... Which is also annoying.

So to recap:

  • Would you please implement a feature that allows the old style to work?
  • What do I do if I already have what you say is needed and it still does not work? Something seems off again unless I have missed something. Do you want me to upload the filter source code here or in another thread?
  • I'm really upset that I just spent the money to renew my subscription only for it to be that my filters no longer work due to (one can assume) no longer allowing single thread execution (and almost immediately making the marking of synchronization pointless). That's very annoying as I don't have a lot of money to begin with and last year when I returned it was only for the filters I wrote!
  • Why wasn't this in the changelog? Or did I miss it? I don't think I did but I did see the synchronization keyword (or whatever it is called in Java) needed to be done and I did that. But this change wasn't added to changelog which means that filters silently stopped working on newer versions of jAlbum. Not really a good thing.

If I seem annoyed it's because I am both annoyed and frustrated. I don't mean the above to be aggressive and if it sounds like it is I apologise but I do have a lot going on and I am rather annoyed that I spent money for something that appears to be a waste of not only money but time fixing code that isn't actually broken (or wasn't broken).

Please advise.
xexyl

Posts: 157
Registered: 1-Sep-2009
Re: Changed filter processing in 23.0.1
Posted: 18 Jul 21, 15:27   in response to: xexyl in response to: xexyl
 
  Click to reply to this thread Reply
Oh and without my filters my skin is utterly pointless too. The entire purpose of it was the reflection filter; Carl suggested it to me years ago. This is very frustrating.
Legend
Forum admins
Helpful Answer
Correct Answer

Point your RSS reader here for a feed of the latest messages in all forums