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

Thursday, July 5, 2012

How to search class in jar files using Jarscan

Suppose you are working on a project and want to include a library jar file which has specific java class. But at the same time you don't have much idea about which jar file to include and you are given with a lot of jar files to choose from. How would you figure out which jar file is the most suitable one.
Well here comes Jarscan to rescue. Jarscan is an executable jar file which scans the jar/zip file and lists jar files which contains the desired class.

Prerequisite:
  • Java 1.4 or higher version should be installed in your system. If your system doesn't have it then you can download it from here.  
  • Jarscan which can be downloaded from here.
Here is the command example below:
java -jar jarscan.jar -help                  #This provides help, how to use jarscan.
java -jar jarscan.jar                        #This works as the command above.
#The following command looks for Activity class root from current directory. 
java -jar jarscan.jar -dir . -class Activity  
You can even search classes through database of libraries online hereIf you want more information about Jarscan you can find it here.

You can try the online services here.

Java class file decompilation

What if you are interested to know more about the class methods, variable, etc. and the only thing that you have is the class file. Don't worry, there is a way to know about these methods, variables etc. even without source file. Javap can help you parsing the class file and providing the information about the  desired class. Javap executable comes with java package. Most of the people either aren't aware of it or don't use it because they rely more on IDE(e.g Eclpse)/build system. Here we are going to use the javap command option for the following class.
 
package com.rakesh.simplewidget;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;


public class ConnectivityReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  NetworkInfo info = (NetworkInfo)intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
  
  if(info.getType() == ConnectivityManager.TYPE_MOBILE){
   
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
     R.layout.widget_layout);
   
   if(info.isConnectedOrConnecting()){
    Toast.makeText(context, "Data packet enabled", Toast.LENGTH_SHORT).show();
    Log.d("RK","Mobile data is enabled");
    remoteViews.setTextColor(R.id.BtEnableDisable, Color.GREEN);
    remoteViews.setTextViewText(R.id.BtEnableDisable, "Enabled");
   }else{
    Toast.makeText(context, "Data packet disabled", Toast.LENGTH_SHORT).show();
    Log.e("RK","Mobile data is disconnected");
    remoteViews.setTextColor(R.id.BtEnableDisable, Color.BLACK);
    remoteViews.setTextViewText(R.id.BtEnableDisable,"Disabled");
   }
   
   ComponentName thiswidget = new ComponentName(context, SimpleWidgetAppWidgetProvider.class);
   AppWidgetManager manager = AppWidgetManager.getInstance(context);
   manager.updateAppWidget(thiswidget, remoteViews);
   
  }
 }

}
Compile the java file and then run the commands below.
 
# Sanity check. If you don't get below message after executing javap command
# then include the java installation folder path in system path.
$javap      
No classes were specified on the command line.  Try -help. 
                                                           
$javap -help      #This command lists all the options available with javap
Usage: javap <options> <classes>...

where options include:
   -c                        Disassemble the code
   -classpath <pathlist>     Specify where to find user class files
   -extdirs <dirs>           Override location of installed extensions
   -help                     Print this usage message
   -J<flag>                  Pass <flag> directly to the runtime system
   -l                        Print line number and local variable tables
   -public                   Show only public classes and members
   -protected                Show protected/public classes and members
   -package                  Show package/protected/public classes
                             and members (default)
   -private                  Show all classes and members
   -s                        Print internal type signatures
   -bootclasspath <pathlist> Override location of class files loaded
                             by the bootstrap class loader
   -verbose                  Print stack size, number of locals and args for methods
                             If verifying, print reasons for failure

#This command decompile the ConnectivityReceiver class file
$javap -c ConnectivityReceiver   
Compiled from "ConnectivityReceiver.java"
public class com.rakesh.simplewidget.ConnectivityReceiver extends android.content.BroadcastReceiver{
public com.rakesh.simplewidget.ConnectivityReceiver();
  Code:
   0: aload_0
   1: invokespecial #8; //Method android/content/BroadcastReceiver."<init>":()V
   4: return

public void onReceive(android.content.Context, android.content.Intent);
  Code:
   0: aload_2
   1: invokevirtual #16; //Method android/content/Intent.getExtras:()Landroid/os/Bundle;
   4: ldc #22; //String networkInfo
   6: invokevirtual #24; //Method android/os/Bundle.get:(Ljava/lang/String;)Ljava/lang/Object;
   9: checkcast #30; //class android/net/NetworkInfo
   12: astore_3
   13: aload_3
   14: invokevirtual #32; //Method android/net/NetworkInfo.getType:()I
   17: ifne 144
   20: new #36; //class android/widget/RemoteViews
   23: dup
   24: aload_1
   25: invokevirtual #38; //Method android/content/Context.getPackageName:()Ljava/lang/String;
   28: ldc #44; //int 2130903041
   30: invokespecial #45; //Method android/widget/RemoteViews."<init>":(Ljava/lang/String;I)V
   33: astore 4
   35: aload_3
   36: invokevirtual #48; //Method android/net/NetworkInfo.isConnectedOrConnecting:()Z
   39: ifeq 81
   42: aload_1
   43: ldc #52; //String Data packet enabled
   45: iconst_0
   46: invokestatic #54; //Method android/widget/Toast.makeText:(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
   49: invokevirtual #60; //Method android/widget/Toast.show:()V
   52: ldc #63; //String RK
   54: ldc #65; //String Mobile data is enabled
   56: invokestatic #67; //Method android/util/Log.d:(Ljava/lang/String;Ljava/lang/String;)I
   59: pop
   60: aload 4
   62: ldc #73; //int 2131099649
   64: ldc #74; //int -16711936
   66: invokevirtual #75; //Method android/widget/RemoteViews.setTextColor:(II)V
   69: aload 4
   71: ldc #73; //int 2131099649
   73: ldc #79; //String Enabled
   75: invokevirtual #81; //Method android/widget/RemoteViews.setTextViewText:(ILjava/lang/CharSequence;)V
   78: goto 117
   81: aload_1
   82: ldc #85; //String Data packet disabled
   84: iconst_0
   85: invokestatic #54; //Method android/widget/Toast.makeText:(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
   88: invokevirtual #60; //Method android/widget/Toast.show:()V
   91: ldc #63; //String RK
   93: ldc #87; //String Mobile data is disconnected
   95: invokestatic #89; //Method android/util/Log.e:(Ljava/lang/String;Ljava/lang/String;)I
   98: pop
   99: aload 4
   101: ldc #73; //int 2131099649
   103: ldc #92; //int -16777216
   105: invokevirtual #75; //Method android/widget/RemoteViews.setTextColor:(II)V
   108: aload 4
   110: ldc #73; //int 2131099649
   112: ldc #93; //String Disabled
   114: invokevirtual #81; //Method android/widget/RemoteViews.setTextViewText:(ILjava/lang/CharSequence;)V
   117: new #95; //class android/content/ComponentName
   120: dup
   121: aload_1
   122: ldc #97; //class com/rakesh/simplewidget/SimpleWidgetAppWidgetProvider
   124: invokespecial #99; //Method android/content/ComponentName."<init>":(Landroid/content/Context;Ljava/lang/Class;)V
   127: astore 5
   129: aload_1
   130: invokestatic #102; //Method android/appwidget/AppWidgetManager.getInstance:(Landroid/content/Context;)Landroid/appwidget/AppWidgetManager;
   133: astore 6
   135: aload 6
   137: aload 5
   139: aload 4
   141: invokevirtual #108; //Method android/appwidget/AppWidgetManager.updateAppWidget:(Landroid/content/ComponentName;Landroid/widget/RemoteViews;)V
   144: return
}

#This command lists the line number and local variables
$ javap -l ConnectivityReceiver   
Compiled from "ConnectivityReceiver.java"
public class com.rakesh.simplewidget.ConnectivityReceiver extends android.content.BroadcastReceiver{
public com.rakesh.simplewidget.ConnectivityReceiver();
  LineNumberTable: 
   line 15: 0

  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      5      0    this       Lcom/rakesh/simplewidget/ConnectivityReceiver;


public void onReceive(android.content.Context, android.content.Intent);
  LineNumberTable: 
   line 19: 0
   line 21: 13
   line 23: 20
   line 24: 28
   line 23: 30
   line 26: 35
   line 27: 42
   line 28: 52
   line 29: 60
   line 30: 69
   line 32: 81
   line 33: 91
   line 34: 99
   line 35: 108
   line 38: 117
   line 39: 129
   line 40: 135
   line 43: 144

  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      145      0    this       Lcom/rakesh/simplewidget/ConnectivityReceiver;
   0      145      1    context       Landroid/content/Context;
   0      145      2    intent       Landroid/content/Intent;
   13      132      3    info       Landroid/net/NetworkInfo;
   35      109      4    remoteViews       Landroid/widget/RemoteViews;
   129      15      5    thiswidget       Landroid/content/ComponentName;
   135      9      6    manager       Landroid/appwidget/AppWidgetManager;


}

#This command prints internal type signatures 
$ javap -s ConnectivityReceiver   
Compiled from "ConnectivityReceiver.java"
public class com.rakesh.simplewidget.ConnectivityReceiver extends android.content.BroadcastReceiver{
public com.rakesh.simplewidget.ConnectivityReceiver();
  Signature: ()V
public void onReceive(android.content.Context, android.content.Intent);
  Signature: (Landroid/content/Context;Landroid/content/Intent;)V
}

#This command shows package/protected/public classes and members (default) 
$ javap -package ConnectivityReceiver 
Compiled from "ConnectivityReceiver.java"
public class com.rakesh.simplewidget.ConnectivityReceiver extends android.content.BroadcastReceiver{
    public com.rakesh.simplewidget.ConnectivityReceiver();
    public void onReceive(android.content.Context, android.content.Intent);
}


#Similar way you can also use -public, -protected -private etc. options


Related topic:
Android/java source code browsing

Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Monday, June 25, 2012

Android Source code browsing

As an engineer,  most of the time you spend on browsing peers' code in your company. Sometimes we think that how these platforms(i.e Android, Java, etc.) have been written? Is there anyway of getting access of source code? Is there any advantage of this?
 Well, there can be certainly some advantages. I would say, you may consider the following points as  advantages.
  • First hand Information. Source code browsing reveals large-scale software program. 
  • Increases your conceptual understanding of platform.
  • Gives idea about how you can do things more precisely and efficiently. It increases your code writing skills.
  • Makes you learn the coding standard and convention followed by the platform.
  • Live examples .
  • You may eventually contribute to the platform enhancement.

There are two ways of browsing the source code:

  1. Copy/clone source code repo.
  2. Online source code browsing.

1. Copy/clone source code repo.

If you have prior knowledge of git/repo and greping code in source directory then this option would be useful for you. If you are not keen to learn Git then please proceed to the next section. You can clone the Android source repo from these two places. 
  • googlesource : If you want to clone the android googlesrouce repo you can follow instruction given here.
  • github : Go here. Select the repositiory which you want to clone. Click on the Readonly button.  You will find url in text field similar to this git://github.com/android/android-module-repository.git and then execute these commands:

$mkdir android-src
$cd android-src
$git clone git://github.com/android/android-module-git-repository.git 

2. Online Source code browsing.

There are various websites available for Android source code browsing. I have listed some of them here. These are arranged in order of their usefulness to developer.
  1. www.grepcode.com : I personally like this website since it is really easy to use and handy. You can see the member function and the directory/package structure on the same webpage. You don't need to navigate around. This website has categorized the source code in different groups based on the module and its functionality. In case you have used Eclipse as an IDE then you will take less time to understand the user interface. There are four tabs Outlines, Files, Hierarchy and Comments, as we have in Eclipse IDE. In Outline tab you can browse methods and variables present in the class and its accessibility(private, protected and public). The File tab shows the folder/directory structure. The Hierarchy tab shows  how a particular class has been derived from other class along with its inheritance hierarchy. The Comments tab may not be so useful however it helps you to comment using your Facebook login. There are four links available on the top of the code frame. They are Find usage, Diff, Raw, Download and HTML widget. Find usage link provides you code snippet giving you the idea about the usage of particular method/variable  in different places. The Diff link provides the difference between the different code versions. The Raw link opens a new browser window which contains the source code.  The Download link itself suggest  what it does. The HTML Widget helps to share the source code. The most useful feature is that you can check the definition of class/variable by clicking on its name. This website also has java source code.
  2. Androidxref.com : This website has index Android 2.3.6, 4.0.4 and 4.1.1 source code. It provides almost similar features as provided by grep.com
  3. www.java2s.com : This is also a good resource. I will rank this site on the second place. It doesn't provide as many features as grepcode does. But still this website can be used for code reference. It also provides code examples which can be really helpful sometimes. 
  4. www.github.com :  This site is not basically designed for code browsing purpose but it can be used for the same. This website organizes the files in the same way as your hardrive does.(I host my source code on github. ;-) }

If you are really into Android and want to browse code on your Android phone then this application can be very handy. You can browse the code on the go.
These two sites java2s and grepcode host java source code and are really useful tools in your armour.

If you want to install git in Ubuntu machine, you may execute command below: 
$sudo apt-get install git

Similar topic:
Python package/library source code browsing

Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius