Ruben Laguna’s blog

EN4J 1.0M2 Released - Evernote Java Client

I finally decided to release the project I was working on the last year: A java desktop client for the Evernote service.

The distributions for Mac OS X, Linux and Windows can be found on the downloads page.

And the source code can be accesses and forked from the git repository on github.

The README for EN4J-1.0M2

                      EN4J
                      
                      
What is it?
-----------

EN4J is a client to the Evernote services written in Java. It designed to
become a replacement to the Evernote client for Windows & Mac. Although 
currently EN4J is a read-only client and cannot fully replace the 
official Evernote client. 

Features
--------
  * Fast search based on Lucene
  * Indexing of word documents, zip files, etc. All doc types supported by Apache Tika
  * Based on Netbeans Platform, runs on Windows, Mac OS X and Linux
  * Open source 

TO DO 
-----

  * Editable notes
  * tags
  * Keyring api
  * Rich-text clipboard copy
  * Ignore diacritical marks during search
  
Bugs
----

If you find any write a bug report on http://github.com/ecerulm/en4j/issues
  
How to build and install
------------------------

First, grab the source from github

git clone git://github.com/ecerulm/en4j.git

Then proceed to the main directory

cd en4j/NBPlatformApp

to build the windows zip distribution do

ant build-zip 

to build the mac os x distribution do 

ant build-mac

Then take the output file in NBPlatformApp/dist


Contribute
----------

Just fork the project from http://github.com/ecerulm/en4j

and send me a pull request with the changes.

Licensing
---------

Please see the file called LICENSE.

Credits
-------

Netbeans team for the Netbeans Plaform and Netbeans IDE

icons: Tango Icon Library http://tango.freedesktop.org/Tango_Icon_Library
icons: Nuvola http://www.icon-king.com/projects/nuvola/
icons: Crystal project http://www.everaldo.com/crystal/
icons: Addictive Flavour. Designed by Mirjami Manninen (http://www.mirkku.com). www.smashingmagazine.com
icons: Bunch of Cool Bluish ICONS http://mebaze.com/ 

GlazedLists: http://publicobject.com/glazedlists/
Apache Thrift: http://incubator.apache.org/thrift/
TimingFramework: https://timingframework.dev.java.net/
Flying Saucer: https://xhtmlrenderer.dev.java.net/
Apache Tika: http://tika.apache.org/
Apache Commons Collections: http://commons.apache.org/collections/
Apache Commons IO: http://commons.apache.org/io/
Apache Commons Math: http://commons.apache.org/math/
Evernote API: http://www.evernote.com/about/developer/api/
Joda Time library: http://joda-time.sourceforge.net/
NekoHTML: http://nekohtml.sourceforge.net/
renderpack: https://renderpack.dev.java.net/
SLF4J: http://www.slf4j.org
Woodstox: http://woodstox.codehaus.org/

Netbeans “Drop to Frame” Debugging

I took me a while to figure out how to rewind the stack while debugging in Netbeans. This feature is called “Drop to Frame” in Eclipse and there is accesible in the toolbar. In Netbeans the feature that allows you to go back in the callstack is called Pop to Here and you invoke it right clicking on the stack. There is also a “Debug / Stack / Pop Topmost Call”
Pop to Here

NullPointerException When Using hideEmptyDocArea

When I put

run.args.extra=-J-Dnetbeans.winsys.hideEmptyDocArea=true

in my project.properties I got a NullPointerException (NPE) at startup. I though it was a bug and I reported it but then I realized that I got the NPE because I had removed/hidden also the editor.wsmode in my layer.xml

1
2
3
4
5
6
7
8
9
10

1
2
3
4
5
6
7
8
9
10
<span class='line'>...
</span><span class='line'>...
</span><span class='line'>&lt;folder name="Windows2">
</span><span class='line'>   &lt;folder name="Modes">
</span><span class='line'>           &lt;folder name="editor_hidden"/>
</span><span class='line'>            &lt;file name="editor.wsmode_hidden"/> 
</span><span class='line'>    &lt;/folder>
</span><span class='line'>&lt;/folder>
</span><span class='line'>...
</span><span class='line'>...</span>

As soon as I removed those entries from the layer.xml hideEmptyDocAre worked perfectly.

Getting Rid of the Grey Empty Area on Your Netbeans Platform Application (RCP)

The short answer is that the gray area that you are seeing in lower bottom of the window is actually the editor area (aka document area) and you can hide it by adding

run.args.extra=-J-Dnetbeans.winsys.hideEmptyDocArea=true

to your platform.properties file. Or by calling

1

1
<span class='line'>System.setProperty("netbeans.winsys.hideEmptyDocArea", "true");</span>

from one of your module’s Installers.

That’s all you need to know but if you are interested on getting some details and references continue reading.

If you create a new Netbeans RCP application and only add TopComponents to modes other than editor (modes which kind=“view”) then you will end up with an empty document area (could be at the bottom, top, left, right or in between TopComponents depending which modes you placed the TCs on). But first, you ask, how do I assign TopComponents to modes? Well you do that in the new Window wizard for example

screenshot of mode assignment

Window Position is actually setting the mode (output, properties, explorer, editor) where the TopComponent will land. You can also do the same in the layer.xml file. See more on modes in these posts.

This grey area that we are talking about… how big it is? and why should it care? Well it not that big from the start but if you resize the window probably it will get noticeable big.

For example this is my test app at startup (the grey area is at the middle)

at startup

and here is how it looks like when I resize it

after resize

Lucene 2.9.0/3.0.1 Memory Leaks

If you are experiencing high memory comsumption with Lucene 2.9.0/3.0.1 it could be due…


  1. … to a recently reported and fixed bug in StandardTokenizer where JFlex generated code was expanding a buffer (zzBuffer) and never trimming it down
    Eclipse Memory Analyzer
    Uploaded with plasq’s Skitch!

  2. … to another recently reported and fixed bug where IndexWriter held references to Readers used in your Fields, (and if you have apache tika’s reader, those can take up a lot of space)
    Eclipse Memory Analyzer-1
    Uploaded with plasq’s Skitch!

Building Apache Tika 0.6 Fails if the Locale Is Not en_US

I tried to build Apache Tika 0.6 yesterday and I couldn’t build it because the tests failed. The failing tests were

  testExcelParserFormatting(org.apache.tika.parser.microsoft.ExcelParserTest)
  testExcelFormats(org.apache.tika.parser.microsoft.ooxml.OOXMLParserTest)

and the failure had to to with the fact that the locale was “es_ES” and the numbering format differs (“1.599,99” and not “1,599.99”)

1
2
3
4
5
6

1
2
3
4
5
6
<span class='line'>$ mvn -version
</span><span class='line'>Apache Maven 2.2.0 (r788681; 2009-06-26 15:04:01+0200)
</span><span class='line'>Java version: 1.6.0_17
</span><span class='line'>Java home: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
</span><span class='line'>Default locale: es_ES, platform encoding: MacRoman
</span><span class='line'>OS name: "mac os x" version: "10.6.2" arch: "x86_64" Family: "mac"@</span>

I changed the locale temporarily to be able to build

export LC_ALL=en_US.UTF-8

so those test no longer failed. But then I run into OutOfMemoryError while running some of the tests so I set MAVEN_OPTS:

export MAVEN_OPTS="-Xmx2048m"

And then mvn install suceeded !. I got the jars

find . -name "*jar"
./tika-app/target/tika-app-0.6.jar
./tika-bundle/target/tika-bundle-0.6.jar
./tika-core/target/tika-core-0.6.jar
./tika-parsers/target/tika-parsers-0.6.jar

JUnit and Netbeans. Injecting in Objects in the Default Lookup

If you need to unit test classes in a netbeans module and the classes use the Lookup.getDefault() to “lookup” things that you want to mock you probably wonder how you can place the mock objects in the default Lookup

Adding objects to the Netbeans’s default Lookup is relatively simple. Here is the answer:


  1. Replace the Lookup instance returned by the Lookup.getDefault()
    by defining a new entry in META-INF/services.

    It’s just a matter of adding a file named org.openide.util.Lookup$Provider in the META-INF/services folder inside your Unit Test source folder. That file should contain the fully qualified class name of your own Lookup.Provider implementation.
    In my case the file contain just the string com.rubenlaguna.en4j.searchlucene.NoteFinderLuceneImplTest because the test class itself implements Lookup.Provider.

    By adding this to META-INF/services you’re actually forcing Lookup.getLookup() to use your Lookup.Provider to obtain the Lookup instance that will be returned

  2. Create you own Lookup.Provider. You can even let your test class implement Lookup.Provider if you only have one test class.

    In this example you can see that I inject a NoteRepository.class into the default lookup.

You can see a living example here

Connect to the Internet via Bluetooth PAN With Mac OS X Snow Leopard

If you want to access the internet via your phone 3G/GPRS connection you can use Bluetooth PAN. In my case I have a Sony Ericsson W715 so the first thing to do is to tell the phone which connection to use Menu > Settings > Connectivity > Bluetooth > Data accounts and select the account that you normally use to browse the net from the phone.

Then turn on bluetooth

Then in the mac:

  1. Go to System Preferences > Bluetooth

  2. Set up new device.


  3. Set up a new device
  4. Click on continue

    Then a screen will appear with a passcode that you have to enter in your phone to do the pairing. if the phone ask you if you want to start the remote control say yes.


  5. In the next screen enter your phone model and apn in my case its online.telia.se and he cid i used 5 because i think itsd unused

    See summary and click quit

  6. Go to System preferences > Network
  7. There is a “Bluetooth PAN” already but that one won’t work: you need to create a new connection

    Press the “+” in the bottom left corner.
    Set the interface to “Bluetooth PAN
    Set the name of the connection to whatever you like. I just typed “W715” in my case.

  8. Turn off Airport or any other connection that you may be using and the go to your newly created connection and click on “Connect”

Cancellable Tasks and Progress Indicators [Netbeans Platform]

Progress indicator (indeterminate mode) which allows to cancel the task
The easiest way of having a cancellable progress indicator (Progress API) for a task in Netbeans Platform Application is the one below but it’s only worth for tasks that don’t update the progress indicator (indeterminate mode) until the task is finished. If you want to update the progress indicator (ProgressHandle) inside the task itself look at the second example.

ProgressHandle indeterminate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<span class='line'>package com.rubenlaguna.en4j.mainmodule;
</span><span class='line'>
</span><span class='line'>import java.awt.event.ActionEvent;
</span><span class='line'>import java.awt.event.ActionListener;
</span><span class='line'>import java.util.logging.Logger;
</span><span class='line'>import org.netbeans.api.progress.ProgressHandle;
</span><span class='line'>import org.netbeans.api.progress.ProgressHandleFactory;
</span><span class='line'>import org.openide.util.RequestProcessor;
</span><span class='line'>import org.openide.util.TaskListener;
</span><span class='line'>
</span><span class='line'>public final class MyCancellableActionNoProgressInformation implements ActionListener {
</span><span class='line'>
</span><span class='line'>    //The RequestProcessor has to have  allowInterrupt set to true!!
</span><span class='line'>    private final static RequestProcessor RP = new RequestProcessor("interruptible tasks", 1, true);
</span><span class='line'>    private final static Logger LOG = Logger.getLogger(MyCancellableActionNoProgressInformation.class.getName());
</span><span class='line'>
</span><span class='line'>    public void actionPerformed(ActionEvent e) {
</span><span class='line'>
</span><span class='line'>        Runnable runnable = new Runnable() {
</span><span class='line'>
</span><span class='line'>            private final int NUM = 60000;
</span><span class='line'>
</span><span class='line'>            public void run() {
</span><span class='line'>                for (int i = 0; i &lt; NUM; i++) {
</span><span class='line'>                    doSomething(i);
</span><span class='line'>                    if (Thread.interrupted()) {
</span><span class='line'>                        LOG.info("the task was CANCELLED");
</span><span class='line'>                        return;
</span><span class='line'>                    }
</span><span class='line'>                }
</span><span class='line'>
</span><span class='line'>            }
</span><span class='line'>
</span><span class='line'>            private void doSomething(int i) {
</span><span class='line'>                LOG.info("doSomething with " + i);
</span><span class='line'>                return;
</span><span class='line'>            }
</span><span class='line'>        };
</span><span class='line'>
</span><span class='line'>        final RequestProcessor.Task theTask = RP.create(runnable);
</span><span class='line'>
</span><span class='line'>        final ProgressHandle ph = ProgressHandleFactory.createHandle("performing some task", theTask);
</span><span class='line'>        theTask.addTaskListener(new TaskListener() {
</span><span class='line'>            public void taskFinished(org.openide.util.Task task) {
</span><span class='line'>                //make sure that we get rid of the ProgressHandle
</span><span class='line'>                //when the task is finished
</span><span class='line'>                ph.finish();
</span><span class='line'>            }
</span><span class='line'>        });
</span><span class='line'>
</span><span class='line'>        //start the progresshandle the progress UI will show 500s after
</span><span class='line'>        ph.start();
</span><span class='line'>
</span><span class='line'>        //this actually start the task
</span><span class='line'>        theTask.schedule(0);
</span><span class='line'>    }
</span><span class='line'>}</span>

leads to

INFO [com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile]: doSomething with 6619
INFO [com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile]: doSomething with 6620
INFO [com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile]: doSomething with 6621
INFO [com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile]: doSomething with 6622
INFO [com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile]: the task was CANCELLED

Progress indicator (determinate mode) which allows to cancel the task

This example show a ProgressHandle that it’s updated from the Runnable and it’s stil cancelable. In this case you are also somewhat to use the more cumbersome catch(InterruptedException) instead of just checking Thread.interrupted(). For some reason I couldn’t get the Thread.interrupted() to work in this case. Doing a Thread.sleep(0) will always throw a InterruptedException if the thread was interrupted (canceling a task will interrupt the thread if the RequestProcessor is created with the interruptThread=true).

Progress indicator (determinate mode)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<span class='line'>package com.rubenlaguna.en4j.mainmodule;
</span><span class='line'>
</span><span class='line'>import java.awt.event.ActionEvent;
</span><span class='line'>import java.awt.event.ActionListener;
</span><span class='line'>import java.util.logging.Logger;
</span><span class='line'>import org.netbeans.api.progress.ProgressHandle;
</span><span class='line'>import org.netbeans.api.progress.ProgressHandleFactory;
</span><span class='line'>import org.openide.util.Cancellable;
</span><span class='line'>import org.openide.util.RequestProcessor;
</span><span class='line'>import org.openide.util.Task;
</span><span class='line'>import org.openide.util.TaskListener;
</span><span class='line'>
</span><span class='line'>public final class MyCancellableAction implements ActionListener {
</span><span class='line'>
</span><span class='line'>    private final static RequestProcessor RP = new RequestProcessor("interruptible tasks", 1, true);
</span><span class='line'>    private final static Logger LOG = Logger.getLogger(MyCancellableAction.class.getName());
</span><span class='line'>    private RequestProcessor.Task theTask = null;
</span><span class='line'>
</span><span class='line'>    public void actionPerformed(ActionEvent e) {
</span><span class='line'>        final ProgressHandle ph = ProgressHandleFactory.createHandle("task thats shows progress", new Cancellable() {
</span><span class='line'>
</span><span class='line'>            public boolean cancel() {
</span><span class='line'>                return handleCancel();
</span><span class='line'>            }
</span><span class='line'>        });
</span><span class='line'>
</span><span class='line'>        Runnable runnable = new Runnable() {
</span><span class='line'>
</span><span class='line'>            private final int NUM = 60000;
</span><span class='line'>
</span><span class='line'>            public void run() {
</span><span class='line'>                try {
</span><span class='line'>                    ph.start(); //we must start the PH before we swith to determinate
</span><span class='line'>                    ph.switchToDeterminate(NUM);
</span><span class='line'>                    for (int i = 0; i &lt; NUM; i++) {
</span><span class='line'>                        doSomething(i);
</span><span class='line'>                        ph.progress(i);
</span><span class='line'>                        Thread.sleep(0); //throws InterruptedException is the task was cancelled
</span><span class='line'>                    }
</span><span class='line'>
</span><span class='line'>                } catch (InterruptedException ex) {
</span><span class='line'>                    LOG.info("the task was CANCELLED");
</span><span class='line'>                    return;
</span><span class='line'>                } 
</span><span class='line'>
</span><span class='line'>            }
</span><span class='line'>
</span><span class='line'>            private void doSomething(int i) {
</span><span class='line'>                LOG.info("doSomething with " + i);                
</span><span class='line'>                return;
</span><span class='line'>            }
</span><span class='line'>        };
</span><span class='line'>
</span><span class='line'>        theTask = RP.create(runnable); //the task is not started yet
</span><span class='line'>
</span><span class='line'>        theTask.addTaskListener(new TaskListener() {
</span><span class='line'>            public void taskFinished(Task task) {
</span><span class='line'>                ph.finish();
</span><span class='line'>            }
</span><span class='line'>        });
</span><span class='line'>
</span><span class='line'>        theTask.schedule(0); //start the task
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    private boolean handleCancel() {
</span><span class='line'>        LOG.info("handleCancel");
</span><span class='line'>        if (null == theTask) {
</span><span class='line'>            return false;
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        return theTask.cancel();
</span><span class='line'>    }
</span><span class='line'>}</span>

leads to

INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5399
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5400
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5401
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5402
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5403
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5404
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5405
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: handleCancel
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: doSomething with 5406
INFO [com.rubenlaguna.en4j.mainmodule.MyCancellableAction]: the task was CANCELLED

OpenJPA, HSQLDB and Proper Shutdown

I’m starting to get tired of OpenJPA/HSQLDB setup that I’ve trying: it seems to give more problems than it solves. Now I discovered that the HSQL db wasn’t been properly shutdown and for reasons that I’m investigating, if the HSQL db is not propertly closed (SHUTDOWN command) it’s impossible to reopen it again. It fails with a IndexOutOfBoundsException.

1
2
3
4
5
6
7
8
9
10
11
12
13

1
2
3
4
5
6
7
8
9
10
11
12
13
<span class='line'>Caused by: org.hsqldb.HsqlException: error in script file line: 33 java.io.IOException: java.lang.IndexOutOfBoundsException in statement [SET TABLE PUBLIC.NOTES INDEX '2883070']
</span><span class='line'>at org.hsqldb.Error.error(Error.java:111)
</span><span class='line'>at org.hsqldb.scriptio.ScriptReaderText.readDDL(ScriptReaderText.java:132)
</span><span class='line'>at org.hsqldb.scriptio.ScriptReaderBase.readAll(ScriptReaderBase.java:88)
</span><span class='line'>at org.hsqldb.persist.Log.processScript(Log.java:721)
</span><span class='line'>at org.hsqldb.persist.Log.open(Log.java:187)
</span><span class='line'>at org.hsqldb.persist.Logger.openPersistence(Logger.java:209)
</span><span class='line'>at org.hsqldb.Database.reopen(Database.java:265)
</span><span class='line'>at org.hsqldb.Database.open(Database.java:235)
</span><span class='line'>at org.hsqldb.DatabaseManager.getDatabase(DatabaseManager.java:222)
</span><span class='line'>at org.hsqldb.DatabaseManager.newSession(DatabaseManager.java:145)
</span><span class='line'>at org.hsqldb.jdbc.JDBCConnection.&lt;init>(JDBCConnection.java:3219)
</span><span class='line'>... 59 more</span>

Annoying. This is not OpenJPA fault, but it gets complicated to actually solve it.

The obvious solution was to add a “;shutdown=true” to the openjpa.ConnectionURL property. That works but it makes the database access unbearable slow. Presumably because it makes HSQL to perform a SHUTDOWN each time OpenJPA closes the connection, and I guess that OpenJPA is closing the connection every couple of INSERTs. This is a guess, I couldn’t confirm it but I see a lot of GC (garbage collection) going on between INSERT and INSERT and I though that I could be that.

UPDATE: Now I’m sure that OpenJPA is closing the connection, I can see it in the HSQL logs. There is a way to enable connection pooling in OpenJPA although is non-trivial.

So “;shutdown=true” is not feasible right now, unless there is something that I could do to raise HSQLDB performance to an acceptable level while using this option.

I was forced to issue the SHUTDOWN myself. In my case in close() in a Netbean’s ModuleInstaller. Which I still don’t like because if the application is not propertly closed itself, the DB won’t be SHUTDOWN and the database will be unreadable again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<span class='line'>public class Installer extends ModuleInstall {
</span><span class='line'>
</span><span class='line'>    private static EntityManagerFactory EMF = null;
</span><span class='line'>    private static EntityManager EM = null;
</span><span class='line'>    private static String connectionURL = null;
</span><span class='line'>    private static final Logger LOG = Logger.getLogger(Installer.class.getName());
</span><span class='line'>
</span><span class='line'>    @Override
</span><span class='line'>    public void close() {
</span><span class='line'>        if (null != EM) {
</span><span class='line'>            //things get cumbersome. We must syncronize access to EM.
</span><span class='line'>            //here and anywhere else where it's used
</span><span class='line'>            synchronized (EM) {
</span><span class='line'>                EM.close();  //we know that there is no active transaction
</span><span class='line'>                             //running because we synchronized the access
</span><span class='line'>                             //and all the other synchonized blocks
</span><span class='line'>                             //never leave the transaction open
</span><span class='line'>                LOG.info("closed EntityManager " + EM);
</span><span class='line'>
</span><span class='line'>                //Issue a SHUTDOWN command via JPA Native Query
</span><span class='line'>                final EntityManager emanager = EMF.createEntityManager();
</span><span class='line'>                LOG.info("JPA Native Query shutdown");                
</span><span class='line'>                emanager.getTransaction().begin();
</span><span class='line'>                emanager.createNativeQuery("SHUTDOWN").executeUpdate();
</span><span class='line'>                emanager.getTransaction().commit();
</span><span class='line'>                emanager.close();
</span><span class='line'>            }
</span><span class='line'>        }
</span><span class='line'>        if (null != EMF) {
</span><span class='line'>            LOG.info("closing EntityManagerFactory " + EMF);
</span><span class='line'>            EMF.close();
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    public static EntityManager getEntityManager() {
</span><span class='line'>        if (EMF == null) {
</span><span class='line'>            Map properties = new HashMap();
</span><span class='line'>            connectionURL = "jdbc:hsqldb:file:" + System.getProperty("netbeans.user") + "/en4j/db";
</span><span class='line'>            properties.put("openjpa.ConnectionURL", connectionURL);
</span><span class='line'>            EMF = javax.persistence.Persistence.createEntityManagerFactory("JpaEntitiesClassLibraryPU", properties);
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        if (null == EM) {
</span><span class='line'>            EM = EMF.createEntityManager();
</span><span class='line'>        }
</span><span class='line'>        synchronized (EM) {
</span><span class='line'>            return java.beans.Beans.isDesignTime() ? null : EM;
</span><span class='line'>        }
</span><span class='line'>    }
</span><span class='line'>}</span>

As I said the everything gets more complicated because know the entityManager could be accessed simultaneosly by two different threads. The ModuleInstall.close() get invoked from a different thread and suddenly we have to use synchronize blocks arround the EntityManager and check that the EntityManager is still open (with EntityManager.isOpen()) everywhere.

Copyright © 2015 - Ruben Laguna - Powered by Octopress