Archive for the ‘Java’ Category

Open source desktop search – and indexing Freemind maps

Friday, December 11th, 2009

I am always keen to investigate open source solutions to everyday problems I face, and my preference is for apps that run in a JRE. This is for two primary reasons:

  • They don’t generally require “installing” by which I mean I can use them on a windows machine without requiring admin rights or permission to update the registry
  • They are portable, so once I have figured out how to best use them to support my day-to-day tasks, I can easily transfer that solution to my Linux PC or Windows laptop

I have been using Freemind for organising all my notes as mindmaps for some time, and I am very pleased with it.

Another area I have been looking into recently is desktop search. The basic offerings in Linux are generally very good, but the Microsoft search solutions are very poor in comparison. I have used Google desktop before – which is very good, but it doesn’t meet the criteria above. To that end I did a bit of searching, and came across a nice pure java desktop search application called DynaQ. It uses various other best-of-breed java libraries to do the extraction and indexing, so is a very powerful search tool. It makes use of Catweasel and Aperture to trawl files and extract content, then uses Apache Lucene for indexing.

One problem I did come across however was that DynaQ did not seem to index my Freemind mind maps. After a bit of digging I discovered that this was because when Freemind saves it’s maps it does not include the standard XML header at the start of the file to identify it as an XML file. As a consequence, when Aperture looks at the file it cannot identify what type of file it is, and does not index it.

There are a few simple steps to remedy the problem:

  • Go to the DynaQ config directory and extract the contents of the apertureMimeConfiguration.xml.jar file
  • Edit the apertureMimeConfiguration.xml file, and amend the content of the XML section so it looks like this:
  • <description>
      <mimeType>text/xml</mimeType>
      <extensions>xml,xsl,xslt,wml,mm</extensions>
      <magicString>&lt;?xml</magicString>
      <magicString>&lt;map</magicString>
    </description>
    
  • Re-add the file to the jar and put it back in the config directory
  • Re-index the directory containing your Freemind files. NOTE: If the directory had been indexed previously you will probably need to update the timestamps on the files to force the indexer to re-index them

You should now be able to search on the contents of your mind maps.

Jackrabbit on Sun App Server 7

Friday, June 29th, 2007

Following on from my earlier post about how to get Jackrabbit working on WebSphere, I also faced some difficulties getting Jackrabbit to run with Sun App Server 7. I think a lot of the difficulties stem from the fact that App Server 7 had a very early implementation of the connector specification – the later versions of the app server seem to be a lot easier to set up. So here is what worked for me:

1) Configure Endorsed Libraries

Before you can deploy on Sun App Server 7 you need to configure the server instance to use a newer version of the SAX parser rather than the one built into JDK1.4. To do this carry out the following steps:

  • In the admin console, click the server instance you want to deploy under
  • Click the JVM Setting tab
  • Click the JVM Options link
  • In the blank JVM Option box at the top, enter:
  •    -Djava.endorsed.dirs=<server_root>/lib/endorsed
    

    Where <server_root> is the path of your server instance directory

  • Apply the changes to the instance
  • Now create an endorsed directory in the server’s lib directory (matching the path specified above
  • Copy recent version of xercesImpl.jar and xalan.jar into your new endorsed directory

You can get more information about ‘endorsed’ libraries here:
http://java.sun.com/j2se/1.4.2/docs/guide/standards/
http://wiki.apache.org/cocoon/EndorsedLibsProblem

2) Edit resource adapter deployment descriptors

Because App Server 7 only supports version 1.0 of the connector spec you will need to edit your ra.xml deployment descriptor slightly to make it deploy. Also, there is no way of configuring your connector in the admin console, so you need to include all the relevant config in the ra.xml and sun-ra.xml files.

So, to make it work with app server 7, carry out the following steps:

  • Download the jackrabbit-jca-1.3.rar file from the jackrabbit site (or the latest version if newer)
  • Unzip the contents to a directory
  • Find the ra.xml file inside the META-INF directory
  • Edit it to read as follows:
  •    <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE connector PUBLIC
            &#039;-//Sun Microsystems, Inc.//DTD Connector 1.0//EN&#039;
            &#039;http://java.sun.com/dtd/connector_1_0.dtd&#039;>
        <connector>
          <display-name>Jackrabbit JCR Adapter</display-name>
          <vendor-name>Apache.org</vendor-name>
          <spec-version>>1.0</spec-version>
          <eis-type>JCR Adapter</eis-type>
          <version>>1.0</version>
          <license>
            <description>ASF</description>
            <license-required>false</license-required>
          </license>
          <resourceadapter>
            <managedconnectionfactory-class>org.apache.jackrabbit.jca.JCAManagedConnectionFactory
                </managedconnectionfactory-class>
            <connectionfactory-interface>javax.jcr.Repository</connectionfactory-interface>
            <connectionfactory-impl-class>org.apache.jackrabbit.jca.JCARepositoryHandle
                </connectionfactory-impl-class>
            <connection-interface>javax.jcr.Session</connection-interface>
            <connection-impl-class>org.apache.jackrabbit.jca.JCASessionHandle
                </connection-impl-class>
            <transaction-support>XATransaction</transaction-support>
            <config-property>
              <config-property-name>HomeDir</config-property-name>
              <config-property-type>java.lang.String</config-property-type>
              <config-property-value> Your repository home directory here
                  </config-property-value>
            </config-property>
            <config-property>
              <config-property-name>ConfigFile</config-property-name>
              <config-property-type>java.lang.String</config-property-type>
              <config-property-value> Your repository config file here
                  </config-property-value>
            </config-property>
            <reauthentication-support>false</reauthentication-support>
          </resourceadapter>
        </connector>
    
  • Now, create a sun-ra.xml file in the same directory containing the following:
  •     <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE sun-connector PUBLIC
              &#039;-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 7.0 Connector 1.0//EN&#039;
              &#039;http://www.sun.com/software/sunone/appserver/dtds/sun-connector_1_0-0.dtd&#039;>
        <sun -connector>
          <resource -adapter jndi-name=" Your JNDI Name Here " max-pool-size="20" steady-pool-size="2"
              max-wait-time-in-millis="300000" idle-timeout-in-seconds="5000">
          </resource>
        </sun>
    
  • Now, re-zip the directory and name it jackrabbit-jca-1.3.rar (or whatever the original filename was)

3) Deploy the resource adapter

  • In the admin console, select the sever instance you want, and click Applications > Connector Modules
  • Click Deploy
  • Click browse, locate your newly edited rar file and click OK
  • On the next page make sure the name you give the app matches the JNDI name you configured in sun-ra.xml, click OK
  • You will probably also have to copy the jar files that were included in the rar file into the server’s lib directory
  • Restart your server instance

4) Make use of your repository

  • You should now be able to make use of your repository using code something like this:
  • InitialContext  ctx = new InitialContext ();
    repository = (Repository) ctx.lookup(" Your JNDI Name Here ");
    SimpleCredentials cred = new SimpleCredentials("login","password".toCharArray());
    Session session = repository.login(cred, null);
    Workspace workspace = session.getWorkspace();
    

    Potential Problems

    I thought I would mention some of the problems I had setting this up so you can avoid making similar mistakes.

    Firstly, make sure your repository.xml is correct, and especially make sure that you have the LoginModule element included – something like:

            <loginmodule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
                    <param name="anonymousId" value="anonymous"/>
            </loginmodule>
    

    Jackrabbit on WebSphere

    Sunday, June 10th, 2007

    I had quite a few problems initially deploying Jackrabbit on Websphere 5.1, so I thought I would document the process to help anyone else who wants to deploy on this environment. I did this using jackrabbit 1.3 on Websphere 5.1, so I can’t guarantee it will work the same on other versions.

    Admittedly I did not know much about using the JCA (Java Connector Architecture) before I started, so I attribute some of my difficulties to my own ignorance.
    If you are interested in a good example of how to use JCA connectors on Websphere, there is a good tutorial available at: http://www-128.ibm.com/developerworks/ibm/library/i-supply1a/

    Initially I got Jackrabbit working in WebSphere by deploying it as a Resource Environment Provider in a similar manner as described here: http://epesh.blog-city.com/jackrabbit_and_glassfish_v2.htm
    Only, this is not a good way of deploying it as multiple web apps are not in fact sharing the same repository in memory in this model, and running multiple repositories against the same physical filesystem is not supported in Jackrabbit. The correct way of deploying a shared jackrabbit repository in Websphere is as a resource adapter. This provides a single shared jackrabbit instance and also provides things like connection pooling for connections to jackrabbit. This can then be accessed by looking it up via JNDI.

    I also have to admit to a certain ignorance about basic JNDI concepts, but the Sun tutorial really helped me to understand it better: http://java.sun.com/products/jndi/tutorial/

    Here is the steps I took to get it working:

    1) Edit the ra.xml in the resource adapter

    • Download the jackrabbit-jca-1.3.rar file from the jackrabbit site
    • Unzip the contents to a directory
    • Find the ra.xml file inside the META-INF directory
    • Edit it to read as follows:
    • <?xml version="1.0" encoding="UTF-8"?>
         <!DOCTYPE connector PUBLIC
            &#039;-//Sun Microsystems, Inc.//DTD Connector 1.0//EN&#039;
            &#039;http://java.sun.com/dtd/connector_1_0.dtd&#039;>
         <connector>
           <display-name>Jackrabbit JCR Adapter</display-name>
           <vendor-name>Apache.org</vendor-name>
           <spec-version>>1.0</spec-version>
           <eis-type>JCR Adapter</eis-type>
           <version>>1.0</version>
           <license>
             <description>ASF</description>
             <license-required>false</license-required>
           </license>
           <resourceadapter>
             <managedconnectionfactory-class>
                org.apache.jackrabbit.jca.JCAManagedConnectionFactory
             </managedconnectionfactory-class>
             <connectionfactory-interface>
                javax.jcr.Repository
             </connectionfactory-interface>
             <connectionfactory-impl-class>
                org.apache.jackrabbit.jca.JCARepositoryHandle
             </connectionfactory-impl-class>
             <connection-interface>
                javax.jcr.Session
             </connection-interface>
             <connection-impl-class>
                org.apache.jackrabbit.jca.JCASessionHandle
             </connection-impl-class>
             <transaction-support>NoTransaction</transaction-support>
             <config-property>
               <config-property-name>HomeDir</config-property-name>
               <config-property-type>java.lang.String</config-property-type>
             </config-property>
             <config-property>
               <config-property-name>ConfigFile</config-property-name>
               <config-property-type>java.lang.String</config-property-type>
             </config-property>
             <authentication-mechanism>
               <authentication-mechanism-type>
                  SimpleCredentials
               </authentication-mechanism-type>
               <credential-interface>
                  javax.jcr.SimpleCredentials
               </credential-interface>
             </authentication-mechanism>
             <reauthentication-support>false</reauthentication-support>
           </resourceadapter>
         </connector>
      
    • Now, re-zip the directory and name it jackrabbit-jca-1.3.rar

    2) Deploy the Resource Adapter

    • To deploy your newly edited resource adapter in Websphere into the admin console:
    • Click Resources > Resource Adapters
    • Click “Install RAR”
    • Click browser and select your RAR file created above
    • Click “Next”
    • Leave all the boxes empty on the next page and click “OK”
    • If you get a ConfigServiceException at this point you may need to set some config manually – scroll down to the bottom of this entry for details on how to do this
    • Go back to Resources > Resource Adapters
    • Click “New”
    • Give your new resource a name (I used Jackrabbit)
    • Select jackrabbit-jca-1.3.rar from the archive path drop-down
    • Click “Apply”

    3) Create a connection factory

    • Scroll down and click “J2C Connection Factories”
    • Click “New”
    • Give your factory a name (I went for Jackrabbit again)
    • Type the jndi name you want to use (I went for jcr/local)
    • Select “BASIC_PASSWORD” from the authentication preference
    • Set both authentication aliases to (none)
    • Set mapping-configuration alias to DefaultPrincipalMapping
    • Click “Apply”
    • Scroll down and click “Custom Properties”
    • Set the values of HomeDir and ConfigFile to appropriate values
    • Save your changes to the master configuration.

    4) Make use of your repository

    • You should now be able to make use of your repository using code something like this:
          InitialContext ctx = new InitialContext();
          repository = (Repository) ctx.lookup("jcr/local");
          SimpleCredentials cred = new SimpleCredentials("login","password".toCharArray());
          Session session = repository.login(cred, null);
          Workspace workspace = session.getWorkspace();
    

    Potential Problems

    I thought I would mention some of the problems I had setting this up so you can avoid making similar mistakes.

    Firstly, make sure your repository.xml is correct, and especially make sure that you have the LoginModule element included – something like:

            <loginmodule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
                    <param name="anonymousId" value="anonymous"/>
            </loginmodule>
    

    Note – the reason I had to specify ‘NoTransaction’ in the config is to work around a bug that I discovered which I have reported to the development team – more details here: http://issues.apache.org/jira/browse/JCR-861

    UPDATE: Looks like as of version 1.4 my bug has been fixed :)

    ConfigServiceException

    In some cases when deploying Jackrabbit on WebSphere I came across this exception:

     com.ibm.websphere.management.exception.ConfigServiceException
       at com.ibm.ws.management.configservice.WorkspaceHelper
                 .getTemplate(WorkspaceHelper.java:274)
       at com.ibm.ws.management.configservice.WorkspaceHelper
                 .getTemplate(WorkspaceHelper.java:208)
       at com.ibm.ws.management.configservice.MOFUtil.newRefObject(MOFUtil.java:78)
       at com.ibm.ws.management.configservice.MOFUtil.createRefObject(MOFUtil.java:1053)
       at com.ibm.ws.management.configservice.MOFUtil.createRefObject(MOFUtil.java:314)
       at com.ibm.ws.management.configservice.DocAccessor
                 .createRootConfigObject(DocAccessor.java:137)
      ...etc...
    

    To get over this:

    First – follow the instructions above, and when you get the error above, do the following:

    1) Create a Resource Adapter

    • In the admin console, click Resources > Resource Adapters
    • Click New
    • Give your adapter a name (e.g. jackrabbit)
    • In the Archive Path, choose to specify the path, and type:
    •     ${CONNECTOR_INSTALL_ROOT}/jackrabbit-jca-1.3.rar
      
    • Click Apply
    • Save your changes to the master repository

    2) Edit the Resource Adapter config manually

  • – Find the resources.xml file for your server instance, this should be in a path like this:
  •     [base_dir]/config/cells/[cellname]/nodes/
                [nodename]/servers/[servername]/
    
  • Open the file, and find the section that looks like this:
  •       <resources.j2c:J2CResourceAdapter xmi:id="J2CResourceAdapter_1179115582274" name="jackrabbit"
           archivePath="${CONNECTOR_INSTALL_ROOT}/jackrabbit-jca-1.3.rar">
            <propertySet xmi:id="J2EEResourcePropertySet_1179115582274">
              <resourceProperties xmi:id="J2EEResourceProperty_1179115582274"
               name="TransactionResourceRegistration" type="java.lang.String" value="dynamic"
               description="Type of transaction resource registration (enlistment).  Valid values are
               either "static" (immediate) or "dynamic" (deferred)."/>
              <resourceProperties xmi:id="J2EEResourceProperty_1179115582275"
               name="InactiveConnectionSupport" type="java.lang.Boolean" value="true"
               description="Specify whether connection handles support implicit reactivation. (Smart
               Handle support). Value may be "true" or "false"."/>
            </propertySet>
          </resources.j2c:J2CResourceAdapter>
    
  • And change the resourceProperties elements:
  •       <resources.j2c:J2CResourceAdapter xmi:id="J2CResourceAdapter_1179115582274" name="jackrabbit"
           archivePath="${CONNECTOR_INSTALL_ROOT}/jackrabbit-jca-1.3.rar">
            <propertySet xmi:id="J2EEResourcePropertySet_1179115582274">
              <resourceProperties xmi:id="J2EEResourceProperty_1179115582274"
               name="HomeDir" type="java.lang.String"/>
              <resourceProperties xmi:id="J2EEResourceProperty_1179115582275"
               name="ConfigFile" type="java.lang.String"/>
            </propertySet>
          </resources.j2c:J2CResourceAdapter>
    

    Restart WebSphere so the changes get picked up and go back to step 3 in the instructions at the start of this post.