Closing streams like a boss

This is one of my favorite tips and I also consider it a good practice.
How to close any java input or output Stream.

/**
* Closes the specified stream.
*
* @param stream The stream to close.
*/
private static void closeStream(Closeable stream) {
if (stream != null) {
   try {
      stream.close();
   } catch (IOException e) {
   Log.e("IO", "Could not close stream", e);
}
} 
Share

Ignore fields at Elastic Search

While I was developing with the Play framework and Elastic Search, I faced a really annoying problem.

In my model I had a Date field. It seems that Elastic Search could not convert it to a valid format of it’s own and I got the following exception:

org.elasticsearch.index.mapper.MapperParsingException: Failed to parse [added]
	at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:309)
	at org.elasticsearch.index.mapper.object.ObjectMapper.serializeValue(ObjectMapper.java:569)
	at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:441)
	at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:567)
	at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:491)
	at org.elasticsearch.index.shard.service.InternalIndexShard.prepareIndex(InternalIndexShard.java:289)
	at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:185)
	at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction.performOnPrimary(TransportShardReplicationOperationAction.java:428)
	at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1.run(TransportShardReplicationOperationAction.java:341)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: org.elasticsearch.index.mapper.MapperParsingException: failed to parse date field, tried both date format [dateOptionalTime], and timestamp number
	at org.elasticsearch.index.mapper.core.DateFieldMapper.parseStringValue(DateFieldMapper.java:343)
	at org.elasticsearch.index.mapper.core.DateFieldMapper.parseCreateField(DateFieldMapper.java:280)
	at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:296)
	... 11 more
Caused by: java.lang.IllegalArgumentException: Invalid format: "2012-03-01 00:00:00.0" is malformed at " 00:00:00.0"
	at org.elasticsearch.common.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:644)
	at org.elasticsearch.index.mapper.core.DateFieldMapper.parseStringValue(DateFieldMapper.java:338)
	... 13 more

Since I didn’t want to search the Date field with Elastic Search at the first place, I found out I could set elastic search to ignore that field and since I’m only interested in searching the “name” and the “description” fields, I could add the @ElasticSearchIgnore annotation at all the other fields.

Now Elastic Search doesn’t bother to parse the Date field nor the others. To be honest, I didn’t found a solution for the Date conversion, but, hey, it works this way ;)

One feature I would like to see (I didn’t found out anything) is to be able to explicitly tell only which fields I want to be searched and exclude all the others.

Share

elastic search!

If you don’t know what elastic search is, you should read about it immediately.
Almost everything you are developing or may develop contains a search section.

As the creator of elastic search are declairing at the project’s first page:

So, we build a web site or an application and want to add search to it, and then it hits us: getting search working is hard. We want our search solution to be fast, we want a painless setup and a completely free search schema, we want to be able to index data simply using JSON over HTTP, we want our search server to be always available, we want to be able to start with one machine and scale to hundreds, we want real-time search, we want simple multi-tenancy, and we want a solution that is built for the cloud.

I use elastic search for the GreekAndroidApps project, I’m developing it with the play framework and it cames handy with a play module ready to use.

One feature I really love (among the others) is the fuzzy search.
This line does a fuzzy search on the “title” or the “description” fields.

BoolQueryBuilder qb1 = boolQuery().should(fuzzyQuery("title", searchString)).should(fuzzyQuery("description", searchString));

So, goodbye “select * from item where content like ‘%term%'” queries!!!

Share

Android Proguard stacktrace example

So, how an obfuscated stacktrace from an application shrunk by Proguard is like?
Take a look at the following examples:

Stacktrace with out Proguard:

E  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pinapps.greekandroidapps/com.pinapps.greekandroidapps.Splash}: java.lang.NullPointerException
...
E  Caused by: java.lang.NullPointerException
E  	at com.pinapps.greekandroidapps.Tools.DataHandler.init(DataHandler.java:58)
E  	at com.pinapps.greekandroidapps.Splash.onCreate(Splash.java:81)
E  	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E  	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

Stacktrace with standard Proguard configuration:

E  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pinapps.greekandroidapps/com.pinapps.greekandroidapps.Splash}: java.lang.NullPointerException
...
E  Caused by: java.lang.NullPointerException
E  	at com.pinapps.greekandroidapps.Tools.c.c(Unknown Source)
E  	at com.pinapps.greekandroidapps.Splash.onCreate(Unknown Source)
E  	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E  	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

Stacktrace with some options for useful obfuscated stacktraces Proguard configuration:

E  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pinapps.greekandroidapps/com.pinapps.greekandroidapps.Splash}: java.lang.NullPointerException
...
E  Caused by: java.lang.NullPointerException
E  	at com.pinapps.greekandroidapps.Tools.c.c(SourceFile:57)
E  	at com.pinapps.greekandroidapps.Splash.onCreate(SourceFile:81)
E  	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E  	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

-printmapping out.map

-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

Share

Android Proguard Error [Fixed]

When using proguard with your Android project, you may face the following proguard error:

Proguard returned with error code 1. See console
 Unexpected error while evaluating instruction:
   Class       = [org/jsoup/parser/TreeBuilder]
   Method      = [insertInFosterParent(Lorg/jsoup/nodes/Node;)V]
   Instruction = [70] aload_2 v2
   Exception   =  (null)
 Unexpected error while performing partial evaluation:
   Class       = [org/jsoup/parser/TreeBuilder]
   Method      = [insertInFosterParent(Lorg/jsoup/nodes/Node;)V]
   Exception   =  (null)
 java.lang.NullPointerException
 	at proguard.evaluation.Variables.aload(Variables.java:264)
 	at proguard.evaluation.Processor.visitVariableInstruction(Processor.java:677)
 	at proguard.classfile.instruction.VariableInstruction.accept(VariableInstruction.java:306)
 	at proguard.optimize.evaluation.PartialEvaluator.evaluateSingleInstructionBlock(PartialEvaluator.java:729)
 	at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlock(PartialEvaluator.java:575)
 	at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlockAndExceptionHandlers(PartialEvaluator.java:533)
 	at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute0(PartialEvaluator.java:221)
 	at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute(PartialEvaluator.java:180)
 	at proguard.optimize.evaluation.LivenessAnalyzer.visitCodeAttribute(LivenessAnalyzer.java:195)
 	at proguard.optimize.evaluation.VariableOptimizer.visitCodeAttribute(VariableOptimizer.java:102)
 	at proguard.classfile.attribute.CodeAttribute.accept(CodeAttribute.java:101)
 	at proguard.classfile.ProgramMethod.attributesAccept(ProgramMethod.java:79)
 	at proguard.classfile.attribute.visitor.AllAttributeVisitor.visitProgramMember(AllAttributeVisitor.java:95)
 	at proguard.classfile.util.SimplifiedVisitor.visitProgramMethod(SimplifiedVisitor.java:91)
 	at proguard.classfile.ProgramMethod.accept(ProgramMethod.java:71)
 	at proguard.classfile.ProgramClass.methodsAccept(ProgramClass.java:439)
 	at proguard.classfile.visitor.AllMethodVisitor.visitProgramClass(AllMethodVisitor.java:47)
 	at proguard.classfile.ProgramClass.accept(ProgramClass.java:281)
 	at proguard.classfile.ClassPool.classesAccept(ClassPool.java:114)
 	at proguard.optimize.Optimizer.execute(Optimizer.java:764)
 	at proguard.ProGuard.optimize(ProGuard.java:325)
 	at proguard.ProGuard.execute(ProGuard.java:114)
 	at proguard.ProGuard.main(ProGuard.java:499)

Fortunately, this error has been fixed at the latest proguard release (4.7), but the Android SDK still uses a previous version.
So all you have to do, it to download the latest proguard version from here, unzip it and copy paste the 3 jars from the “lib” folder to your Android-SDK folder at ANDROID_SDK_HOME/tools/proguard/lib and replace the old jars.

Backing up is always a smart and proper move.

Share