Check if a class extends another at Runtime : Java

Summary :

  • If you want to know whether or not a Class extends another, use Class#isAssignableFrom(Class)
  • Class#isAssignableFrom(Class) also returns true if both classes are same
  • To find if an object is instance of a class use instanceof operator
  • To know if a class is direct sub class of another class then use Class#getSuperClass().equals(Class)

Setup :

We have an interface MyInterface and three classes MyBaseClass, MySubClass and SomeOtherClass with the below hierarchy.

interface MyInterface {
}

class MyBaseClass implements MyInterface {
}

class MySubClass extends MyBaseClass {
}

class SomeOtherClass {
}   

Tests:

   

public class Test {
  
  public static void main( String[] args ) {
    
    /*
     * Checking if a class is same as or is a superclass or superinterface
     * 
     * of another class (the class in parameter)
     */
    System.out.println( MyBaseClass.class.isAssignableFrom( MyBaseClass.class ) );// true : same class
    System.out.println( MyBaseClass.class.equals( MyBaseClass.class ) );// true : same class
    System.out.println( MyBaseClass.class.isAssignableFrom( MySubClass.class ) );// true : superclass
    System.out.println( MyInterface.class.isAssignableFrom( MySubClass.class ) );// true : superinterface
    System.out.println( MyBaseClass.class.isAssignableFrom( SomeOtherClass.class ) );// false : the two classes has no relation
    System.out.println( MySubClass.class.isAssignableFrom( MyBaseClass.class ) );// false : MySubClass is not the superclass
    
    /*
     * Checking if a object is instance of a class
     */
    
    IMyInterface object = new MyBaseClass( );
    System.out.println( object instanceof MyInterface ); // true
    System.out.println( object instanceof MyBaseClass ); // true
    System.out.println( object instanceof MySubClass ); // false
    System.out.println( object instanceof SomeOtherClass );// false
    
    /*
     * check if a class is direct superclass of another
     */
    
    System.out.println( MySubClass.class.getSuperclass( ).equals( MyInterface.class ) );// false : its not a directsuper class, interface
    System.out.println( MyBaseClass.class.getSuperclass( ).equals( MyInterface.class ) );// false : its not a directsuper class, interface
    System.out.println( MySubClass.class.getSuperclass( ).equals( MyBaseClass.class ) );// true : MyBaseClass is extending MySubClass
  }
}
   

Full code :

   

public class Test {
  
  public static void main( String[] args ) {
    
    /*
     * Checking if a class is same as or is a superclass or superinterface
     * 
     * of another class (the class in parameter)
     */
    System.out.println( MyBaseClass.class.isAssignableFrom( MyBaseClass.class ) );// true : same class
    System.out.println( MyBaseClass.class.equals( MyBaseClass.class ) );// true : same class
    System.out.println( MyBaseClass.class.isAssignableFrom( MySubClass.class ) );// true : superclass
    System.out.println( MyInterface.class.isAssignableFrom( MySubClass.class ) );// true : superinterface
    System.out.println( MyBaseClass.class.isAssignableFrom( SomeOtherClass.class ) );// false : the two classes has no relation
    System.out.println( MySubClass.class.isAssignableFrom( MyBaseClass.class ) );// false : MySubClass is not the superclass
    
    /*
     * Checking if a object is instance of a class
     */
    
    IMyInterface object = new MyBaseClass( );
    System.out.println( object instanceof MyInterface ); // true
    System.out.println( object instanceof MyBaseClass ); // true
    System.out.println( object instanceof MySubClass ); // false
    System.out.println( object instanceof SomeOtherClass );// false
    
    /*
     * check if a class is direct superclass of another
     */
    
    System.out.println( MySubClass.class.getSuperclass( ).equals( MyInterface.class ) );// false : its not a directsuper class, interface
    System.out.println( MyBaseClass.class.getSuperclass( ).equals( MyInterface.class ) );// false : its not a directsuper class, interface
    System.out.println( MySubClass.class.getSuperclass( ).equals( MyBaseClass.class ) );// true : MyBaseClass is extending MySubClass
  }
}

interface MyInterface {
}

class MyBaseClass implements MyInterface {
}

class MySubClass extends MyBaseClass {
}

class SomeOtherClass {
}

      
   

superclass "javax.servlet.http.HttpServlet" not found on Java Build Path - solution

You might (normally) get the error following error on a dynamic java web project created through maven on Eclipse IDE. The solution is simple :
Error :
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path   
Error Location :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
Solution 1)
Edit pom.xml to include servlet-api-x.x.jar in your dependencies:
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.1</version>
  <scope>provided</scope>
</dependency>   
Solution 2)
Go to Project->Properties->Target Runtimes . And add your server container eg. : Apache Tomcat


Java Obsfucate Password - Replace with asterisk

Obsfucate password : 

Rreplace everything except first and last character by asterisk ( * ), if  the password is less than ALLOWED_LENGTH characters long obfuscate it entirely i.e., prints asterisks

Code :
   
//Test 
System.out.println( getObfuscatedPassword( "" ) ); //returns null
System.out.println( getObfuscatedPassword( "pwdd" ) ); //returns ****
System.out.println( getObfuscatedPassword( "mySecurePassword" ) ); // returns m**************d


//Method 
public static String getObfuscatedPassword( String password ) {
   
   int ALLOWED_LENGTH = 5;
   
   if ( null == password || "".equals( password.trim( ) ) ) {
    return null;
   }
   
   StringBuilder builder = new StringBuilder( );
   
   if ( password.length( ) < ALLOWED_LENGTH ) {
   
    for ( int i = password.length( ); i != 0; i-- ) {
     builder.append( "*" );
    }
   
    return builder.toString( );
   }
   
   builder.append( password.charAt( 0 ) );
   
   for ( int i = password.length( ) - 2; i != 0; i-- ) {
    builder.append( "*" );
   }
   
   return builder.append( password.substring( password.length( ) - 1 ) ).toString( );
}

   

change maven local repository path - symbolic links

Let's suppose we want to change the local maven repo path (default : c:\users\user_name\.m2\repository) to some other real folder - lets say e:\repo  - so that the contents from e:\repo folder are mapped to the default folder location.

This might be useful when .m2 folder on your C: drive is taking too much space. In such case, you can move the content to another drive ( e:\repo) and have a symbolic link on C:\ drive instead - so that all the configuration remains intact.


The following command creates a link folder "repository" in /.m2 folder and points to the source e:\REPO

C:\>mklink /d c:\users\gtiwari\.m2\repository e:\REPO


Note:


using symbolic links on windows

Using symbolic links (MKLINK comand) on windows:

Suppose we want to create a link of folder 'e:\source' to c:\target\bridge then, use the following command:

C:\>mklink /d c:\target\bridge e:\source

Syntax : mklink /d TARGET SOURCE_DIR

  • This command creates a link folder "bridge" in c:\target\ where you can see the contents from e:\source.
For more info :
Visit: http://ss64.com/nt/mklink.html - 

Linux find command

The find command is one of the most important and much used command in Linux systems. find command is used to search and locate list of files and directories based on conditions you specify for files that match the arguments. In this article we will get familier with linux find command.

First things first, to get more knowledge on any linux command we can use linux manual page using man <command_name>. For more information about find you can use man find and you'll get in depth description on how we can use linux command.

Basic use of find looks somewhat like below

find .

Let's get familier which the syntax of find. In above example we have two parts

  1. find : find is the command itself
  2. . : . (dot) represents the path from where we want to search. We can pass any path here and find will start to look from the path what was provided.

If you run the command, you will get list of all the files and directories that is inside the path that was given as argument.

But I assume you don't want to search for all files. You may want to search for file from / directories that has specific name. To seach for specific file / directories we can use -name option. Here's an example of find which search for the file / directories with the name .gitignore

find . -name '.gitignore'

# OUTPUT

./.gitignore

You can see that we are using . here. If you wanted to start search from root you are free to pass / as you seach directory.

Did you notice that I kept on saying search for file or directories. By default find will try to match the option of -name on both directories and files. If you want to limit your search for file or directories you can use -type option.

find . -type d -name 'img'

# OUTPUT

./_site/img
./img

If you pass d argument on -type option your search will limit to directories only.

find . -type f -name '.gitignore'

# OUTPUT

./.gitignore

If you pass f argument on -type option your search will limit to files.

Linux system are case sensitive. What if you want to seach file ignoring the case. -iname can be use to do just that.

find . -iname '.gitignore'

You can also search file with certain extention. Let's search file with .css extention

find . -type f -name '*.css'

# OUTPUT
./css/bootstrap-theme.css
./css/pygment_highlights.css
./css/main-minimal.css
./css/bootstrap.css
./css/bootstrap.min.css
./css/normalize.css
./css/bootstrap-theme.min.css
./css/main.css

We can use * to indicate any character. We can also search files with multiple extention. Suppose you want to search file with .css and .html. You can do that with

find . -name '*.css' -or -name '*.html'

# OUTPUT

./_layouts/post.html
./_layouts/default.html
./_layouts/page.html
./_layouts/base.html
./index.html
./css/bootstrap-theme.css
./css/pygment_highlights.css
./css/main-minimal.css
./css/bootstrap.css
./css/bootstrap.min.css
./css/normalize.css
./css/bootstrap-theme.min.css
./css/main.css

Notice how we are joining the option -name in above syntax using -or. -or can be used with its alias -o You may have guessed that we can use -and too. Here's an example of find using -and.

# find . -name 'm*' -name '*.css'
find . -name 'm*' -and -name '*.css'

# OUTPUT
./_site/css/main-minimal.css
./_site/css/main.css
./css/main-minimal.css
./css/main.css

Now that you know about -or and -and, you may have imagined endless possibilities of search patterns. Just a quick note, if you use two -name without -and on above example it would act as -and. Quick hint !! you have -not option too. -not can be used with its alias !. -or , -and and -not can be used with other option too.

You can also control how deep you want to search usign -maxdepth

find . -maxdepth 1 -name '*.html'

# OUTPUT
./index.html

You can use find to search the files / directories based on modified, changed or accessed days and minutes.

For days you have -mtime, -atime, -ctime and for minutes you have -mmin, -amin, -cmin. Option prefixed with m denotes modified, a denotes accessed and c denotes changed.

find . -mtime 20
find . -atime 20
find . -ctime 20
find . -mmin 20
find . -amin 20
find . -cmin 20

We can also use + and - symbol number provied. For example

find . -mtime +5

Above command find the file which was not modified in last 5 days.

find . -mtime -5

Above command find the file which was modified within last 5 days.

You can also go for range of days and minutes. Here's an example

find . -mtime +5 -mtime -10

Above command finds the files / directories that are modifined between 5 to 10 days

find . -mmin +5 -mtime -10

Above command finds the files / directories that are modifined between 5 to 10 minutes.

To search the file that has specific size you can use -size option

find . -type f -size 2M

Above command search file that has exactly 50M. We can also use + and - symbol on the number here. For example

find . -type f -size -2M

This command will find the files that has size of 2MB and less

For range you can do

find . -type f -size +2M -size -10M

To find empty file or directory you can use -empty option

find . -empty

find also has option -user, -group and -perm which lets you search the file that is associated with specific user, group or if the file has certain permission.

You can also perform certain operation on the files / directories that are searched and found using -exec option.

For this example here is the list of files and dir that I have

-rw-rw-r--  1 aman aman    0 Oct  7 10:30 four.html
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 one.txt
drwxrwxr-x  2 aman aman 4096 Oct  7 10:31 somedir
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 three.txt
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 two.php

To rename the two.php to two.html you can issue following command

find . -type f -name 'two.php' -exec mv -f {} two.html \;

# ls -l

-rw-rw-r--  1 aman aman    0 Oct  7 10:30 four.html
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 one.txt
drwxrwxr-x  2 aman aman 4096 Oct  7 10:31 somedir
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 three.txt
-rw-rw-r--  1 aman aman    0 Oct  7 10:30 two.html

Let's explain what -exec is performing. After -exec we are writing the command that we want to execute. In our example we wanted to change two.php to two.html. Notice we are using {} placeholder in source section. To end the -exec command we are using \;.

I know on destination we used static text. What if we want to use change all html files to php now. Here's the command

find . -type f -name '*.html' -exec bash -c 'mv "$1" "${1%.html}".php' - {} \;

Now that's a complex command. Let's me explain what's happening.

First we are passing bash -c '<command_to_execute_inside_bash>' - <param_to_send> on -exec. The command will execute for each entry that is found by find command. If find finds 5 files with *.html it will run the command 5 times.

Lets look at the command that we passed for execution i.e mv "$1" "${1%.html}".php.

$1 is the first argument that was passed to command. For example if we have 2 file with html extention. It will send 1st file found to command as its 1st argument and command execution will take place. Then, it goes for 2nd find found and will again pass the file name as its 1st argument.So if we have two file one.html and two.html our find command will find the one.html first and it will execute our command which argument one.html. So on first execution $1 value will be one.html and on second execution $1 will be two.html

Next we have "${1%.html}".php. In a simple term if $1 represents one.html then "${1%.html}" will represent one. So "${1%.html}".php will represent one.php. Visit Bash Referrence Manural for more detail.

If we have two file one.html and two.html. When our command execute the first time ti will look like bash -c 'mv one.html one.php' and second time bash -c 'mv two.html two.php'.

Here's the output

-rw-rw-r-- 1 aman aman    0 Oct  7 10:30 four.php
-rw-rw-r-- 1 aman aman    0 Oct  7 10:30 one.txt
drwxrwxr-x 2 aman aman 4.0K Oct  7 10:31 somedir
-rw-rw-r-- 1 aman aman    0 Oct  7 10:30 three.txt
-rw-rw-r-- 1 aman aman    0 Oct  7 10:30 two.php
find is very handy command and I hope this article helped you get an insight on how you can use find to search files and directories you need.