Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Setting JAVA_HOME on Raspberry Pi

The new Raspbian build comes with Java 1.8 pre-installed. You can check the current java version by issuing following command;

java -version


java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)

In order to set environment variable "JAVA_HOME"; you can set it on ~/.bashrc file.

nano ~/.bashrc


then add the following into the end of file and save changes.

export JAVA_HOME="/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt"
export PATH=$PATH:$JAVA_HOME/bin

Then on you next login you can try out this;

export

which should ideally print;

declare -x JAVA_HOME="/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt"
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/bin"

java.lang.SecurityException: invalid SHA1 signature file digest

This weekend we came up with a issue when trying to verify a jar already signed using JarSigner in JDK7 or JDK8(JarSigner? seriously WTH is that? read this). When the same jar file is signed with JDK6 it is working fine. Here how to reproduce this error;

java security
Java Jar Security

Reproducing the issue

Sign a jar file in JDK6 using;
jarsigner -keystore /path/to/keystore.jks dummy.jar alias

alias: is the alias identifying the private key that's to be used to sign the JAR file, and the key's associated certificate

Switch into JDK7 and sign again using(but with another key);
jarsigner -keystore /path/to/another/keystore.jks dummy.jar otheralias

You might wondering why two private keys / keystores are used. In the real world scenario usually JARS are signed by the official organization who realeases it (First time signed). Another organization might use these JARS and may need to sign on their private key(Second time signed).

However, If you tried to verify the above JAR file;
jarsigner -verify dummy.jar 

You will get the following error;
jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for Test.class

This error usually happens when jarsigner digest algorithms mismatched. But how it is related here?

Analyzing the problem and the solution

Finally we found that the issue. Problem is with the mismatch of the default signing algorithm in JDK6, 7 and 8. If you are not specifying -digestnlg option;

JDK6 Doc: by default, SHA-1 will be used.
JDK 7 Doc: by default, SHA-256 will be used.

Solution

You may use "-digestalg SHA1" to sign the already signed JAR with a different certificate key. For example;
jarsigner -keystore /path/to/keystore.jks -digestalg SHA1 dummy.jar alias

Further Observations

I have further observed that; Eventhough "-digestalg SHA1" solves(or work as a workaround), I am not clear about the jarsigner's verification behaviour.
  1. Suppose we are signing a JAR with SHA1 then signing SHA256 with the same key / alias verification never fails. 
  2. Signing a JAR with SHA1 then signing SHA256 with different keys / alias broke the verification.
  3. Signing a JAR with SHA1 then again SHA1 with same/different keys /alias never fails(This is what we did to solve the issue).

This is also reported in stackoverflow[1]. But according to the java doc[2], it says It is also possible for a JAR file to have mixed signatures.

Links

[1]http://stackoverflow.com/questions/12614139/what-prevents-java-from-verifying-signed-jars-with-multiple-signature-algorithms

[2]http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html#sthref18

Therefore, the workaround for the problem is,



Support for Selenium IDE export as Java / TestNG / WebDriver

This is a very brief entry for those who seeks support for exporting Selenium scripts. Currently Selenium IDE supports exporting selenium scripts into `Java / TestNG / Remote Control(RC)`. WebDriver is the successor of the old Remote Control(RC). Exporting test cases generated by Selenium IDE to `Java / TestNG / WebDriver` is not officially supported at the time writing this blog entry.

Therefore, I created PR request and hopefully will be merged soon. The benefits of this PR are;

1). Export Test Case As.. -> Java / TestNG / WebDriver

Export your reordered test cases into Java, TestNG and WebDriver supported `.java` files.


2). Export Test Suite As.. -> Java / TestNG / WebDriver

This will create a XML file conformed to TestNG Test Suite documentation . According TestNG docs;
A suite is represented by one XML file. It can contain one or more tests and is defined by the <suite> tag.

Therefore, expected outcome is a `testng.xml` file with <suite> tags.


Link to the Pull Request(PR)

The Pull Request and code changes are available on https://github.com/SeleniumHQ/selenium/pull/326.

Download the Selenium IDE - XPI

You can download the build of this fix based on the Selenium IDE 2.8.0 from the following link http://goo.gl/N2Cp4O.

Note: You can find latest releases of the selenium IDE in http://www.seleniumhq.org/download/

JDK 1.7 fails on JIBX: java.lang.VerifyError error

This is what I got when running WSO2 AS JiBX sample on JDK 1.7. By the way What is JiBX???
JiBX differs from other data binding techniques supported by Axis2 in that it allows you to use your own Java data objects (as opposed to Java data objects generated from a schema definition). JiBX also provides a nicer form of an unwrapped Web services interface than is supported by the other data binding techniques[1].
     [bind] Error running binding compiler
     [bind] java.lang.VerifyError: Expecting a stackmap frame at branch target 12
     [bind] Exception Details:
     [bind]   Location:
     [bind]     org/wso2/appserver/jibx/library/beans/Book.JiBX_jibx_unwrapped_newinstance_1_0(Lorg/wso2/appserver/jibx/library/beans/Book;Lorg/jibx/runtime/impl/UnmarshallingContext;)Lorg/wso2/appserver/jibx/library/beans/Book; @1: ifnonnull
     [bind]   Reason:
     [bind]     Expected stackmap frame at this location.
     [bind]   Bytecode:
     [bind]     0000000: 2ac7 000b bb00 0a59 b700 744b 2ab0     
     [bind] 
     [bind] at java.lang.Class.getDeclaredMethods0(Native Method)
     [bind] at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
     [bind] at java.lang.Class.getDeclaredMethods(Class.java:1860)
     [bind] at org.jibx.binding.Compile.compile(Compile.java:278)
     [bind] at org.jibx.binding.ant.CompileTask.execute(CompileTask.java:248)
     [bind] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
     [bind] at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
     [bind] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     [bind] at java.lang.reflect.Method.invoke(Method.java:606)
     [bind] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
     [bind] at org.apache.tools.ant.Task.perform(Task.java:348)
     [bind] at org.apache.tools.ant.Target.execute(Target.java:435)
     [bind] at org.apache.tools.ant.Target.performTasks(Target.java:456)
     [bind] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
     [bind] at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
     [bind] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
     [bind] at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
     [bind] at org.apache.tools.ant.Main.runBuild(Main.java:851)
     [bind] at org.apache.tools.ant.Main.startAnt(Main.java:235)
     [bind] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
     [bind] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
     ...
     BUILD FAILED

The hardest sentence that a developer ever don't want to see on `ant` is the "BUILD FAILED" message. So, we have lost in a java.lang.VerifyError.

Root Problem?

Let's dig into the problem. We are getting a java.lang.VerifyError error. Why we getting such a thing?

Because JVM class loader checks the byte codes of the class for various purposes;
  • Variables are initialized before they are used.
  • Method calls match the types of object references.
  • Rules for accessing private data and methods are not violated.
  • Local variable accesses fall within the runtime stack.
  • The runtime stack does not overflow.

If one of the above is failed, JVM will think the class is corrupted and/or the class will not be loaded. This strict verification is an important security consideration. It avoids unexpected errors that breaks the execution of the program ad injecting malicious codes into the Java programs.

Java 7 introduced a strict verification and changed the class format slightly to contain a stackmap, used to verify the code is correct. As a result; on the exception details, it says; `Expected stackmap frame at this location`.

So What is the Solution?

If you are using ANT builders; you can use ANT_OPTS environment variable to following;

export ANT_OPTS=-noverify


Or as a workaround you can add -noverify to the JVM arguments in order to disable verification. In Java 7 it was also possible to use -XX:-UseSplitVerifier to use the less strict verification method, but that option was removed in Java 8.


Additional Note:

In Java world, dynamic java code is protected with the three line of protection layers as shown in below image. The first line on defense is ByteCode Verifier. The verifier reads the bytecodes before it is run and make sure it is well behaved according to the basic rules of the java language.

Niemeyer P., Leuck, D., "Learning Java, Fourth Edition", O'REILLY Atlas online version[1]
A trusted java compiler will not produce such malicious bytecodes, but it is possible to an outsider to malform the bytecodes of a class and it is java verifier's  job to detect such certain instances. For additional readings please refer [2].

Links

[1]  WSO2 AS Documentation, Available Online: https://docs.wso2.com/display/AS521/JiBX+Data+Binding [2] Niemeyer P., Leuck, D., "Learning Java, Fourth Edition",chapter 1,  O'REILLY Atlas, Available Online: http://chimera.labs.oreilly.com/books/1234000001805/ch01.html#learnjava3-CHP-1-SECT-5.1

How to fix Java Apps Getting Blurred on Retina Displays MAC OS X

Have you experienced this too???. My MacBook was shipped with JDK 1.6.0. So I installed JDK 1.7u07. Soon after I realized that all java based applications(or running on the newer JVM) are getting blurred. Look closer on these two images;

`Android Studio` on JDK 1.7u07;


`Android Studio` on JDK1.7u40;

It is negligible, isn't it???

Of course it is not a big issue but having eyes on the screen for long hours will be definitely yelling; "There is something....!!!". So I decided to dig into the problem and found out, that is because JDK 1.7 support issue.

AWT/ Swing under the JDK 1.7(as before 1.7u40) had an issue with HiDPI displays. HiDPI (High Dots Per Inch) also known as Apple's "Retina Display" marketing name, which are screens with a high resolution in a relatively small format[1].

So What is the Solution???




According to this change log it is been fixed on JDK1.7u40. HiDPI or retina support is available on [2];
  • Java 6
  • Java 7u40ea or greater
  • Java 8
So the solution is to upgrade you current JDK into one of above matching criteria. 

Have a Happy Coding Day !!! 

Links
[1] https://wiki.archlinux.org/index.php/HiDPI
[2] http://stackoverflow.com/questions/15181079/apple-retina-display-support-in-java-jdk-1-7-for-awt-swing