Thunderbird Keeps Giving An Alarm For A Past Event; How To Get Rid Of Them

I ran into a strange issue where Thunderbird just simply would not quit reminding me about the calendar events from one day in one of my remote calendars. I suppose in all fairness this is really the Lighting extension which did this. I dug around in the extensions sources on my system, and I found where it was happening, but didn't have time to really formulate a real "fix". But, what I noticed is it was using a cache to hold this information. So, I started looking at the folders under my profile.

What I noticed was the folder calendar-data directly under my profile. On Linux this can be found at ~/.thunderbird/yourprofile/calendar-data. The next thing I noticed was the cache.sqlite file along with some others you most likely want to keep. I opened the database in sqliteman, and I could sure enough find the entries there. I had already deleted the events from my remote calendar through my phone, and my other events, future and recurring, still exist in my remote calendar.

I thought, I can either find all the rows for these, as there are multiple tables in the database, or I can just blow away the cache, and not really worry about it. My preferences for how many days to cache would determine how much would be downloaded again; on my office or home connection, it would not be a problem.

For some, blowing away the cache may be a big deal, so know what that means for you if that is the option you choose, but for me, it was a great option. I made sure I synchronized to push any of my changes, shutdown Thunderbird, deleted cache.sqlite, and restarted Thunderbird. As predicted it downloaded everything again, and the constant alarm stopped.

Problem Solved!


Java Module Systems The EDT and ClassLoader Issues

As mentioned in Java Module Systems SwingWorker, Runnable, Thread and ClassLoader Issues, where invokeLater and invokeAndWait are discussed, the EDT is a separate thread with its own context classloader, and this is most likely the system classloader. It is important to understand this.

If you create a user interface in a modular system, such as the NetBeans RCP, upon a user action logic will run on the EDT, and if in that logic you access classes by name, create new instances of them, or perform casts and those classes could possibly be in more than one module, you will run into classloader collision issues. I will restate here that this also affects EventQueue.invokeLater and invokeAndWait.

Along with collision issues, you need to also understand that certain class access may be blocked depending on the classloader being used once you set the thread context classloader. Imagine you have some classes your current UI components classloader can see; they are part of its dependencies. Those dependencies classloaders may not have access to each other. If you use a classloader which does not have access to some classes to set the thread context classloader, then access will be blocked to those classes, and your logic will not work.

Suppose there is a button and it has an action listener attached to it. It could be written as:
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent evt){
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
//here we are actually taking the current instances classloader
//which could be slightly better than
//create instances, cast, load classes by name

The above could make an assumption it is the only possible some.specificpackage.MyActionListener to be within any module in the system at one time were it to use MyActionListener.class.getClassLoader(), and if that were not to be the case, you would need to get creative in the manner in which you get a classloader into this object.

The code does slightly guard against that since it uses getClass().getClassLoader() versus the static MyActionListener.class.getClassLoader() which would unequivocally infer it is expected to be the only one in the system per the way the class and classloader are being accessed. This means the instances classloader will be used, and if the instance was created using a specific classloader, and it is correct, then the code will simply work. If the classloader is not correct, then the logic which created the instance will need to be fixed.

This is another subtle way in which classloader issues can creep into the domain of concurrency and Java modular systems. You can use this information to ensure you have protected your modules logic from being broken by other modules at runtime which you probably will not have tested against.

Remember, if you use 3rd party libraries in a module, or you are writing one, it is highly probable and definitely possible others will too, and you may use the same ones. Whether the library is the same version or not, unless it is accessed in the context of a shared module classloader, i.e. the library is itself in a module versus a simple JAR dependency and all other modules use it this way, it can cause collision and access issues.