Friday, February 27, 2015

CRC32 calculation on Java and Objective-C

CRC32.md

One time I had to calculate CRC32 checksum for image files on Java and Objective-C. But I could not get the results matched when I tried to read the file via UIImagePickerController on Objective-C. I knew the result from Java was correct because this website returned the same checksum. The myth was finally resolved when I loaded the file from resource by using NSBundle.

Source code

code snippet in Java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.CRC32;

...
try {
    Path path = Paths.get("path/to/image.jpg");
    byte[] data = Files.readAllBytes(path);
    Checksum checksum = new CRC32();
    checksum.update(data, 0, data.length);
    long result = checksum.getValue();
    System.out.println("file crc32 cheksum: " + result);
} catch (IOException e){
    e.printStackTrace();
}

code snippet in Objective-C

you will need to add libz.dylib in Linked Frameworks and Libraries in General tab on Xcode.

#include <zlib.h>;

...
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"jpg"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
uLong crc = crc32(0L, Z_NULL, 0);
long long result = crc32(crc, [data bytes], [data length]);
NSLog(@"file crc32 checksum %llu", result));

Tuesday, February 10, 2015

Create executable jar on Eclipse

1. After the coding is complete, run the project as Java Application. This step is mandatory for Eclipse to create the Launch configuration info.

2. Identify the Launch configuration name by going to "Run Configurations..." (right click on project -> Run As). On the "Main" tab, there is a Name textbox on the top. The value is editable.

3. Export the project as "Runnable JAR file" (Right click on project -> Export). On the next step, select the Launch configuration for the name and set the Export destination.

4. After the jar is generated, run the application by java -jar <app_name.jar>

Monday, January 12, 2015

The Hello World JNI example

The Hello World JNI example

A simple example to use native code (C/C++ in this tutorial) via JNI (Java Native Interface). The Java program will take the input from user, and then pass the value to native code to print out on console.

Setup

  • Linux Mint - a modern, elegant and comfortable Linux distro
  • OpenJDK - the JDK on Linux Mint
  • gcc - the c compiler

Installation

Make usre the software is installed properly

$ javac -version
javac 1.7.0_75
$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
...

Development

Demo.java

package com.example.jni;

public class Demo {

    // load native library at runtime
    static {
        System.loadLibrary("myNative");
    }

    // declare a native method
    public native void helloNative(String message);

    public static void main(String[] args) {
        new Demo().helloNative(args[0]);
    }
}

generate the header file com_example_jni_Demo.h

path/to/java/src $ javah com.example.jni.Demo

no need to modify the header file, but it declares the method to implement

JNIEXPORT void JNICALL Java_com_example_jni_Demo_helloNative
  (JNIEnv *, jobject, jstring);

myNative.c

#include 
#include "com_example_jni_Demo.h"

JNIEXPORT void JNICALL Java_com_example_jni_Demo_helloNative(JNIEnv *env, jobject obj, jstring javaString)
{
    const char *message;
    message = (*env)->GetStringUTFChars(env, javaString, 0);
    printf("native echo: %s\n", message);
}

generate the Shared Library which will be libmyNative.so

path/to/java/src $ gcc -shared -fPIC -o libmyNative.so -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux myNative.cdino

compile and run the program

path/to/java/src $ javac com/example/jni/Demo.java
path/to/java/src $ java -Djava.library.path=path/to/java/src Demo

To run the Java program on Eclipse, add -Djava.library.path=path/to/shared/library to Run configurations -> Arguments -> VM arguments