Sunday, July 5, 2015

LuceneAppEngine 3.0.0 is out!

Why all this time for the next release? A lot of things: personal commitments and working on LAE Kerbymart fork, Twist, Lucene 5 breaking changes took me a lot of time. But finally after a long time I'm glad to announce the release of a new version of the LAE project.

What's new in LAE 3.0.0 release?

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 3.0.0 and Lucene 5.0.0;
  • Live Demo up and running with the latest new LAE 3.0.0 and Lucene 5.0.0.


Enjoy!


Wednesday, September 17, 2014

LuceneAppEngine 2.2.0 is out!

I'm glad to announce the release of a new version of the LAE project.
What's new in LAE 2.2.0 release?

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 2.2.0 and Lucene 4.10.0;
  • Live Demo up and running with the latest new LAE 2.2.0 and Lucene 4.10.0.


Enjoy!


LuceneAppEngine 2.1.0 is out!

I'm glad to announce that I released (10 August 2014) a new version of the LAE project.
What's new in LAE 2.1.0 release?

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 2.1.0 and Lucene 4.9.0;
  • Live Demo up and running with the latest new LAE 2.1.0 and Lucene 4.9.0.


Enjoy!


LuceneAppEngine 2.0.1 is out!

I'm glad to announce that I released (23 July 2014) a new version of the LAE project.
This new version is contains several bugfix and performance improvements.
All previous versions of LAE are now deprecated.
What's new in LAE 2.0.1 release?
  • Various BugFix;
  • Performance improvements;
  • Details and compatibility matrix here.

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 2.0.1, added pagination of results;
  • Live Demo up and running with the latest new LAE 2.0.1 and Lucene 4.8.1.


Enjoy!


Thursday, May 29, 2014

LuceneAppEngine 2.0.0 is out!

I'm glad to announce the release of a new version of the LAE project.
What's new in LAE 2.0.0 release?
  • Upgraded LAE to Java 7;
  • LAE 2.0.x compatible with Lucene 4.8.x;
  • Upgraded to Objectify 5.0.x;
This new LAE version wasn't released as 1.x because now it needs Java 7 (or greater).

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 2.0.0 and Lucene 4.8.1;
  • Upgraded LAE Examples to Java 7 (code refactoring);
  • Changed LAE Examples to the latest official Google App Engine maven plugin (appengine-maven-plugin);
  • Live Demo up and running with the latest new LAE 2.0.0 and Lucene 4.8.1.


Updated the Lucene/Java compatibility matrix;

Enjoy!


Tuesday, April 15, 2014

Java 8 - what's new!

Hello!


I want only to share with you what I think to be a very good article useful to check what's new in Java 8.


I think that this overview is balanced, I mean that is not verbose and not shallow.


I wrote too many words, let's check this guide https://leanpub.com/whatsnewinjava8/read.
Enjoy!

Related posts:

Sunday, April 13, 2014

New LuceneAppEngine 1.0, 1.1, 1.2 out!

After a while, I'm glad to announce the release of new versions of the LAE project.
I've been busy and this has delayed the release. But the waiting is now over.
What's new in LAE project? A lot!:
  • LAE new LAE official site https://code.google.com/p/luceneappengine;
  • LAE 1.2.x compatible with Lucene 4.7.x;
  • LAE 1.1.x compatible with Lucene 4.6.x;
  • LAE 1.0.x compatible with Lucene 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x;
  • Objectify updated to 4.1 (released to maven central);
  • Artifacts released into Maven Central (no longer need to add specific repository into your pom.xml)
  • Source code moved to GitHub (for easier contributions
  • LAE no longer compatible with Lucene 3.x, if you need it refer to the previous lucene-appengine site (discontinued).

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to the latest new LAE 1.2.0 version;
  • Live Demo up and running with the latest new LAE 1.2.0 version.


Migration instructions any older lucene-appengine to the new luceneappengine artifacts:
  1. Remove any previous repository reference (lucene-appengine and objectify) from your pom.xml
  2. Remove any dependency of older lucene-appengine artifact and add the following to your pom.xml:
            
            
            
                    com.googlecode.luceneappengine
                    luceneappengine
                    1.2.0
            
            
                    org.apache.lucene
                    lucene-core
                    4.7.1
            
            
                    org.apache.lucene
                    lucene-analyzers-common
                    4.7.1
            
    ....
    
        
    refer to this page for detailed Lucene compatibility matrix;
  3. Change your WEB-INF/appengine-web.xml removing the "-", no more present in new LAE artifacts:
    
    ...
        
            
        
    ...
        
            ...
            
            
        
    
    
  4. Add to your WEB-INF/web.xml
            
            ...
                
                    ObjectifyFilter
                    com.googlecode.objectify.ObjectifyFilter
                
                
                    ObjectifyFilter
                    /*
                
            ...
            
        
    see objectify documentation for details and alternatives.


Enjoy!


Monday, July 22, 2013

Lucene AppEngine growing: steps to Maven Central, GitHub and new site

Lucene AppEngine is changing; a lot of news are coming, keep yourself steady on the chair. Works are still in progress but in a few days everything should be complete.
The most important news that are coming to the Lucene AppEngine project are:
  1. Project site will move from lucene-appengine.googlecode.com to luceneappengine.googlecode.com;
  2. Official source repository will move from Mercurial to Git and from Googlecode to GitHub, but everything will be mirrored into the googlecode repository
  3. Lucene AppEngine maven artifacts will be deployed into Maven Central
  4. GroupId will change from com.googlecode.lucene.appengine into com.googlecode.luceneappengine;
  5. Version policy will change with a new policy, details below;
  6. Lucene AppEngine now works with Objectify 4


Why these choices?
  1. A new site means new policy under each and every point of view. The old site will remain untouched and sourcecode, maven repository... will still be available. That's why the official site is changed;
  2. I think that GitHub platform now is the best for an opensource project like LAE. Lucene AppEngine is about google appengine platform so the official site will still be into googlecode as mirror (simplest thanks to git);
  3. Maven Central is one of the biggest news for LAE and it simplifies the management of LAE for people using Maven or Ivy or Gradle etc... Having an artifact you need into Maven Central is a pleasure for each developer. Having Lucene AppEngine into maven central does not mean that downloads will disappear from googlecode sites, I will take care of it but only for released versions (this means that SNAPSHOTS version can be not manually downloaded from official site);
  4. GroupId is changed to be more compliant to artifacts standard;
  5. Version policy will be changed to simplify management of versions, LAE versions will be vertically splitted into two main line (one supporting Lucene 3 and the other one Lucene 4) and LAE will be no more released for each version of the Lucene project, but will be released when needed so if you want to upgrade your Lucene version you have to look at the compatibility matrix that I will write
  6. Lucene AppEngine uses Objectify 3, now Objectify 4 is nearly released as stable so there is no reason to keep version 3; With Objectify 4 LAE will be more stable, quick and ready for a production environment, my thanks go to every people developing this good framework for AppEngine environment;

What will happen to live demo site and demo source code/examples? Nothing those will go on and will continue using LAE but with the new version deployed into maven central.
Now you can also use GitHub for your contribution, source code here.
How to take a snapshot version of LAE? Simply add the repository to your pom.xml or in your settings.xml the sonatype snapshot repository:
...
    
        sonatype.oss.snapshots
        Sonatype OSS Snapshot Repository
        http://oss.sonatype.org/content/repositories/snapshots
        false
        true
    
...


A new LAE is coming; Stay tuned!


Friday, July 19, 2013

Java: Maps with enums as keys

Life is hard and world is big, but sometimes when we see another person where we don't expected him to be, we say "how little the world is" (at least this happens in Italy).
I think that world is really little at least for another reason :-p

Which one?! Simple!
A lot of people use HashMap (or other map implementations) filled with enum keys instead of using EnumMap.

Java standard SDK provides java.util.EnumMap specifically to manage maps with enums as keys, this map is size optimized and potentially quicker than HashMap counterpart. Furthermore an EnumMap mantains the natural order of Enum.

That's all, so lets try to change your code from
public class EnumMapMain {
    
    enum Tires {
        SOFT,
        MEDIUM,
        HARD
    }
    
    public static void main(String[] args) {
        Map tiresToDescription = new HashMap();
        tiresToDescription.put(Tires.HARD, "Worst grip of all tires but with a greate durability");
        tiresToDescription.put(Tires.MEDIUM, "Medium grip and medium durability");
        tiresToDescription.put(Tires.SOFT, "A lot of grip but usefull only for few laps");
        
        StringBuilder buildDescription = new StringBuilder("Tires Types:");
        for (Tires tire : Tires.values()) {
            buildDescription.append("\n\t").append(tire).append("\t-->\t").append(tiresToDescription.get(tire));
        }
        System.out.println(buildDescription.toString());
    }
}
to
public class EnumMapMain {
    
    enum Tires {
        SOFT,
        MEDIUM,
        HARD
    }
    
    public static void main(String[] args) {
        Map tiresToDescription = new EnumMap(Tires.class);
        tiresToDescription.put(Tires.HARD, "Worst grip of all tires but with a greate durability");
        tiresToDescription.put(Tires.MEDIUM, "Medium grip and medium durability");
        tiresToDescription.put(Tires.SOFT, "A lot of grip but usefull only for few laps");
        
        StringBuilder buildDescription = new StringBuilder("Tires Types:");
        for (Tires tire : Tires.values()) {
            buildDescription.append("\n\t").append(tire).append("\t-->\t").append(tiresToDescription.get(tire));
        }
        System.out.println(buildDescription.toString());
    }
}

It's simple and unpainful! It brings some memory and performance improvements to your code ;-)

Related posts:

Thursday, June 6, 2013

Lucene AppEngine 4.3.0 is out!

I'm glad to announce the release of new versions of Lucene AppEngine project.
What's new in LAE project:
  • Released LAE-4.2.1 compatible with Lucene 4.2.1 and Lucene 4.3.0
  • Released LAE-4.3.0-SNAPSHOT compatible with Lucene 4.3.0 and above (I hope!);
  • All released libraries available into maven repository, see project home page for details;

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to latest LAE 4.3.0-SNAPSHOT version;
  • Live Demo up and running with latest LAE 4.3.0-SNAPSHOT version.


Enjoy!


Sunday, May 5, 2013

Lucene AppEngine 4.2.1 is out!

I'm glad to announce the release of new versions of Lucene AppEngine project.
What's new in LAE project:
  • Released LAE-4.2.0 as stable with performance improvements and memcache support
  • Released LAE-4.2.1-SNAPSHOT compatible with Lucene 4.2.1;
  • All released libraries available into maven repository, see project home page for details;

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to latest LAE 4.2.1-SNAPSHOT version;
  • Live Demo up and running with latest LAE 4.2.1-SNAPSHOT version.

A new note is out for the simplified configuration of LAE. Add into your appengine-web.xml:

    
        
    

WARNING: If you are using a SNAPSHOT version of LAE using Maven, you must add the specific jar name of the snapshot, you can see the specific jar name typing on command line:
    mvn clean package && ls -lR target/ | grep lucene-appengine
The snapshot jar name can change with every SNAPSHOT release so if you are falling into the "java.lang.NoClassDefFoundError: sun.misc.Unsafe is a restricted class" error check the version of the jar.

Enjoy!


Monday, April 29, 2013

Snippets moved to Gist GitHub

Hello all!
Do you remember my posts with pom.xml snippets? So I moved and unified the snippet in these posts: ...into GitHub Gist
Now contribution are more simple than ever and this is the reason of because I choose to use Gist GitHub to share that snippets and any future snippet.
Follow me and contribute on GitHub Gist .

Thursday, April 25, 2013

Openfire Room Service plugin

Hi all!
Openfire is a real time collaboration (RTC) server licensed under the Open Source Apache License. It uses the only widely adopted open protocol for instant messaging, XMPP (also called Jabber). Openfire is incredibly easy to setup and administer, but offers rock-solid security and performance.
I shared a little plugin for Openfire that allows you to manage chat rooms via http requests. The plugin, named Room Service Plugin, is inspired to the User Service plugin version 1.3.2. Full source code available on GitHub .

That plugin has been developed for Openfire 3.7.1 and I don't know if it works with Openfire 3.8.1.

Tuesday, April 23, 2013

Contribution to Spring Data Mongo

It's time to share with you my first little little little little contribution to SpringSource/spring-data-mongodb
If you don't know spring-data-mongodb, the abstract is:
Provide support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
Here is the contribution .
That's all!

Sunday, April 21, 2013

Less invasive configuration for Lucene AppEngine

I'm glad to announce a new configuration for Lucene AppEngine project.
If you used Lucene AppEngine maybe you've encountered this error java.lang.NoClassDefFoundError: sun.misc.Unsafe is a restricted class. Yes! I've already solved that problem but in an invasive and unfunny way; but now...

Just add this into your appengine-web.xml and everything will be fine.

    
        
    


What's new in LAE examples and in Live Demo:
  • Updated with latest gae-sdk library
  • Updated look and feel with Bootstrap.
  • Updated with new simplified configuration of LAE;

Enjoy!


Saturday, April 20, 2013

Eclipse: Convert to if-!-return

Yes I use Eclipse and I'm excited for the new feature 'Convert to if-!-return' that is coming with Eclipse 4.3 Kepler. Whoever has read my previous post Coding: Why I hate "single line else" can understand why I'm so happy!

Here the Eclipse description of 'Convert to if-!-return' Quick Assist:
Ever encountered a long if statement that can be safely inverted to an early return, so that you can ignore the code that follows, and make it easier to understand? Now, you can just use a Quick Assist (Ctrl+1) on the if statement to do this refactoring



Related posts:

Sunday, March 24, 2013

Java: Bad protected log and no chance to fix it

This post is related to the final question asked in one of mine previous post Java: Bad protected final log. How to resolve the problem of a bad log declaration, like the one below, without editing the code?
    protected final Logger log = LoggerFactory.getLogger(this.getClass());

First of all you should use slf4j , bridge every log framework to slf4j, then use logback as implementation for logging.
Then simply add or edit your logback configuration introducing the caller class as parameter. For example if you have a logback.xml file like this:

    
        
            %-5level %logger - %msg %xEx%n
        
    

    
        
    


change it into:

    
        
            %-5level %class - %msg %xEx%n
        
    

    
        
    



Now the problem is solved but remember: you are paying with performance, finding the caller requires more computational time than printing logger's name.

Related posts:

Wednesday, March 20, 2013

Lucene AppEngine 4.2 is out

I'm glad to announce the release of new versions of Lucene AppEngine project.

Big news! Performance improvements and memcache support!


What's new in LAE project:
  • Released LAE 4.1.0 as stable with performance improvements;
  • Released LAE-3.6.3-SNAPSHOT with performance improvements (base on Lucene 3.6.2);
  • Released LAE-4.2.0-SNAPSHOT with performance improvements and memcache support;
  • All released libraries available into maven repository, see project home page for details;

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to latest LAE 4.2.0-SNAPSHOT version;
  • Live Demo up and running with latest LAE 4.2.0-SNAPSHOT version.

Enjoy!


Saturday, February 16, 2013

Lucene AppEngine 4.1 is out

I'm glad to announce the release of new versions of Lucene AppEngine project.
What's new in LAE project:
  • Released LAE 3.6.2 as stable powered by Lucene 3.6.2;
  • Released LAE 4.0.0 as stable powered by Lucene 4.0;
  • Released LAE 4.1.0-SNAPSHOT powered by Lucene 4.1;
  • For each release slf4j framework updated to 1.7.2;
  • All released libraries available into maven repository, see project home page for details;
  • Minor performance improvements/refactoring.

What's new in LAE examples and in Live Demo:
  • Aligned LAE Examples to latest LAE 4.1.0-SNAPSHOT version;
  • Live Demo up and running with latest LAE 4.1.0-SNAPSHOT version.

Enjoy!


Wednesday, November 7, 2012

Java: Bad protected final log

Another post about logging? Yes!
Writing good log statements is something hard to learn, in my honest opinion every log statement should follow these principles:
  • contains complete information: in other words, there's no need to scroll to understand the meaning of the log or to read other related informations;
  • log output is in a single line (see also logging in single line for grep);
  • contains informations about where the log is placed (package and class).
About the latter point I'll share with you some bad techniques I've seen. Some people get tired about logging, so, in order to write less code, they do something like this:

    package foo.bar;
    
    import org.slf4j.*;

    public class SharedClass {
        protected final Logger log = LoggerFactory.getLogger(this.getClass());
        
        public void doLog(int count) {
            log.info("Called doLog with count = '{}'.", 1);
            for (int i = 0; i < count; i++) {
                callAnotherMethod(i);
            }
        }
        public void callAnotherMethod(int i) {
            log.info("Called method with i = '{}'.", i);
        }
    }
    public class SubClass extends SharedClass {
        @Override
        public void callAnotherMethod(int i) {
            log.info("Called method with i = '{}'.", i);
        }
    }
Where's the problem? Run this main and try to understand what happens:
    public class Main {
        public static void main(String[] args) {
            SharedClass parent = new SharedClass();
            SharedClass child = new SubClass();
            child.doLog(10);
            parent.doLog(10);
        }
    }
Pretend that you are reading the log output below without any knowledge of the application, and pretend that you are searching for a bug and the anomaly is on row one (e.g. because count is one but method is called five times):
13:21:40.261 [main] INFO  foo.bar.SubClass - Called doLog with count = '1'.
13:21:40.264 [main] INFO  foo.bar.SubClass - Called method with i = '0'.
13:21:40.264 [main] INFO  foo.bar.SubClass - Called method with i = '1'.
13:21:40.264 [main] INFO  foo.bar.SubClass - Called method with i = '2'.
13:21:40.264 [main] INFO  foo.bar.SubClass - Called method with i = '3'.
13:21:40.264 [main] INFO  foo.bar.SubClass - Called method with i = '4'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called doLog with count = '1'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called method with i = '0'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called method with i = '1'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called method with i = '2'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called method with i = '3'.
13:21:40.264 [main] INFO  foo.bar.SharedClass - Called method with i = '4'.
Hence you start searching the class... but?! There is no log statement like that in SubClass! And now?! Do you try to search a string like "Called doLog with count"? And what to do if the string doesn't exist because it's composed using concatenation?
Anybody could answer me: "It's simple! There should be a super class", but where? And if a method, somewhere around the code, is using the Logger of another class?

Solution: declare Logger as private static final Logger log, initialized by the same class as where it's declared. Yes the log fields is lower case because it is not a constant, it is a final reference (see also stackoverflow).
    package foo.bar;
    
    import org.slf4j.*;

    public class SharedClass {
        private static final Logger log = LoggerFactory.getLogger(SharedClass.class);
        
        public void doLog(int count) {
            log.info("Called doLog with count = '{}'.", 1);
            for (int i = 0; i < count; i++) {
                callAnotherMethod(i);
            }
        }
        public void callAnotherMethod(int i) {
            log.info("Called method with i = '{}'.", i);
        }
    }
    public class SubClass extends SharedClass {
        private static final Logger log = LoggerFactory.getLogger(SubClass.class);
        @Override
        public void callAnotherMethod(int i) {
            log.info("Called method with i = '{}'.", i);
        }
    }
Eventually we can see a more debuggable log output, like the one below:
13:23:57.351 [main] INFO  foo.bar.SharedClass - Called doLog with count = '1'.
13:23:57.354 [main] INFO  foo.bar.SubClass - Called method with i = '0'.
13:23:57.354 [main] INFO  foo.bar.SubClass - Called method with i = '1'.
13:23:57.354 [main] INFO  foo.bar.SubClass - Called method with i = '2'.
13:23:57.354 [main] INFO  foo.bar.SubClass - Called method with i = '3'.
13:23:57.354 [main] INFO  foo.bar.SubClass - Called method with i = '4'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called doLog with count = '1'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called method with i = '0'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called method with i = '1'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called method with i = '2'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called method with i = '3'.
13:23:57.354 [main] INFO  foo.bar.SharedClass - Called method with i = '4'.
Thank you everybody for your patience.
A question: what to do if you can't edit all the wrong Logger declarations? Wait for Go to my next post to have the answer! :-)

Related posts: