Tuesday, 6 January 2015

Java File I/O (NIO.2)

Background

Initially all Java had for supporting Files was java.io.File class. But it lacked lot of functional features like copying file, handling symbolic links, getting attributes of file etc. As a result new set of I/O APIs were introduced in Java 7 called NIO.2 (New I/O).



We will see three important things in this post
  1. Path interface and it's functions
  2. FileVisitor (Walking a file tree)
  3. Directory WatchService (Watching a directory for changes)

 Understanding Path interface

Path is an interface in java.nio.file package. It extends 3 other interfaces
  1. Comparable<Path>
  2. Iterable<Path>
  3. Watchable
You can get instance of Path using methods defines in class java.nio.file.Paths . Following is the code to understand Path interface and it's methods -

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class HelloWorld {

    public static void main(String args[]) {

        Path p1 = Paths.get("C:\\Users\\.\\athakur\\Desktop\\..\\Desktop");
        Path p3= Paths.get("C:\\Users\\.\\athakur\\Desktop\\..\\Desktop\\abc.txt");
        Path p4 = Paths.get("C:\\Users\\athakur\\Desktop\\abc.txt");
        
        //GET methods
        System.out.println("File name : " + p1.getFileName());
        System.out.println("Root File : " + p1.getRoot());
        System.out.println("Name Count : " + p1.getNameCount());
        System.out.println("Get Name: " + p1.getName(2)); // thows java.lang.IllegalArgumentException if index is > getNameCount() - 1
        System.out.println("Get Parent: " + p1.getParent());
        
        for(Path p : p1) {
            System.out.println("Element : " + p);
        }
        
        //TO methods
        System.out.println("Uri : " + p1.toUri());
        System.out.println("File : " + p1.toFile());
        System.out.println("Normalize : " + p1.normalize());
        System.out.println("Absoulute  : " + p1.toAbsolutePath()); //absolute does not normalize
        
        try {
            System.out.println("RealPath  : " + p1.toRealPath());// Throw IOException if File does not exist
            //returns absolute normalized path
        } catch (IOException e) {
            e.printStackTrace();
        } 
        
        System.out.println(p3.equals(p4));
        System.out.println(p3.toAbsolutePath().equals(p4.toAbsolutePath()));
        
        try {
            System.out.println(p3.toRealPath().equals(p4.toRealPath()));
            //Make sure Paths are normalized and absolute before comparing
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        System.out.println("File exists : " + Files.exists(p1));
        
    }


}


Output :

File name : Desktop
Root File : C:\
Name Count : 6
Get Name: athakur
Get Parent: C:\Users\.\athakur\Desktop\..
Element : Users
Element : .
Element : athakur
Element : Desktop
Element : ..
Element : Desktop
Uri : file:///C:/Users/./athakur/Desktop/../Desktop/
File : C:\Users\.\athakur\Desktop\..\Desktop
Normalize : C:\Users\athakur\Desktop
Absoulute  : C:\Users\.\athakur\Desktop\..\Desktop
RealPath  : C:\Users\athakur\Desktop
false
false
true
true

Another interesting method is relativize()

        Path p5 = Paths.get("C:\\Users\\athakur\\Desktop");
        Path p6 = Paths.get("C:\\Users\\athakur\\Desktop\\Dir1\\abc.txt");
        
        System.out.println("p5 relative to p6 : " + p6.relativize(p5));
        System.out.println("p6 relative to p5 : " + p5.relativize(p6));


Output :

p5 relative to p6 : ..\..
p6 relative to p5 : Dir1\abc.txt

NOTE:
  • The relativize() method needs that both paths be relative or both be absolute. IllegalArgumentException will be throws if a relative path is used with an absolute path and vice versa.

You can also use resolve() method to create a new Path. The object on which resolve() is invoked forms the base of the new Path and the input is appended to it. Eg.

Path path1 = Paths.get("C:\\Users\\athakur\\Desktop");
Path path2 = Paths.get("abc.txt");
System.out.println(path1.resolve(path2));


Output :
C:\\Users\\athakur\\Desktop\\abc.txt

 NOTE:
  • In above example input argument was a relative path but if it is an absolute path the base is ignored and the copy of absolute argument Path is returned.
  • Like relativize() , resolve() also does not cleanup up path symbols like '..' or '.'. You can clean it up with normalize() though. Again normalize() does not check if file actually exists. That's the job for toRealPath().


Note some of the following important points
  1. Most of the methods in Path interface do not throw IOException if underlying file or directory does not exist except the method toRealPath(). That's because Path just is a representation of file in the file system not the actual file.
  2. To carry out functionality like creating/deleting directories, copying you can use methods provided in java.nio.file.Files class.
  3. toRealPath() method normalizes the path as well and converts to absolute path and returns.
  4. java.io.File class has toPath() method that return Path instance from a File instance. Similarly Path has toFile() method to get File instance.
  5. You can also get Path instance from underlying file system as -
    • FileSystems.getDefault().getPath("C:\\Users\\athakur\\Desktop") OR
    • FileSystems.getDefault().getPath("C:","Users","athakur","Desktop")
  6. Also note the Root of a file 'c:/' in above case is never counted as path element. getName(index) method will return element at position= index and position starts from 0 at element after root. So to sum up getName(int index) method is zero indexed and file systems root excluded.
  7. You can compare two paths with compareTo() method [as Path interface extends Comparable interface] or you can use equals(). compareTo() method will  compare paths character by character where as equals() will check if two paths are pointing to same file. However note for equals() to work each path should be normalized and converted to absolute path (you can use toRealPath()). Or you can simply use Files.isSameFile(path1, path2) 
  8. isSameFile() method will first check if two Paths are same irrespective of files actually exist or not. If they are same true is returned. If it returns false then the files are actually located and compared. If files does not exist then IOException is thrown. 

Below diagram summaries general way to create a Path instance.
NOTE :
  • Unlike File class Path interface contains supports for symbolic links.
  • Path is an interface. You cannot directly create a instance of Path and have to use one of the factory methods provided. This is done deliberately since files are system dependent and by using a factory method Java handles system specific details for you.
  • You can create a Path variable using a varagrg String arguments like Paths.get(String,String,...). Benefit of this is that you dont have to worry about the separator which is platform dependent. You can also get it as System.getProperty("path.separator")
  • Path object is not a file but a representation of a location within your file system. So you can perform operations like getting the root directory or parent directory without the file actually existing. However some methods like Path.toRealPath() do need file to exist and throw checked exception.
  • getRoot() method returns root element of the Path object or null of the Path is relative.
Notes :
  1. Files.isDirectory() follows links by default
  2. Files.deleteIfExists() would throw a DirectoryNotEmptyException if it had contents. It will work for empty directory or a symbolic link.
  3. Files.lines() returns a Stream<String> and Files.readAllLines() returns a List<String>. Files.lines() reads the file in a lazy manner, while Files.readAllLines() reads the entire file into memory all at once; therefore Files.lines() works better on large files with limited memory available
  4. Also see - Walking a directory using Streams API in java8 

Walking a File Tree (walkFileTree)

NOTE : Below method is for java 7. For Java 8 we have Files.walk(path) method that returns Stream<Path> which you can iterate on in a depth first pattern. See Walking a directory using Streams API in java8 

java.nio.file.Files class has two method that are provided to traverse File tree. They are - 

  • Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
  • Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor)

Both methods take instance of Path to start with and an instance of  FileVisitor that describes what action to taken when each file is visited.

FileVisitor interface provides various methods to take actions at various junctions. Methods are -

  1. visitFile()
  2. preVisitDirectory()
  3. postVisitDirectory()
  4. visitFileFailed()
You need to create a class that implements interface java.nio.file.FileVisitor . Or simply you can extends SimpleFileVisitor class and override necessary methods.

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;


public class TestFileVisitor extends SimpleFileVisitor<Path> {
    
    public FileVisitResult visitFile(Path path, BasicFileAttributes fileAttributes) {
        System.out.println("Visiting File :" + path.getFileName());
        return FileVisitResult.CONTINUE;
    }

    public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes fileAttributes) {
        System.out.println("Accessiong Directory : " + path );
        return FileVisitResult.CONTINUE;
    }
    
    public static void main(String args[])
    {
        Path startPath = Paths.get("C:\\Users\\athakur\\Desktop\\Dir1");
        System.out.println("Staring to traverse File tree");
        try {
            Files.walkFileTree(startPath, new TestFileVisitor());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


Output : 

Staring to traverse File tree
Accessiong Directory : C:\Users\athakur\Desktop\Dir1
Accessiong Directory : C:\Users\athakur\Desktop\Dir1\Dir2
Visiting File :File2 - Copy.txt
Visiting File :File2.txt
Accessiong Directory : C:\Users\athakur\Desktop\Dir1\Dir3
Visiting File :File3 - Copy.txt
Visiting File :File3.txt
Visiting File :File1 - Copy.txt
Visiting File :File1.txt

Note :
  1. You can use walkFileTree() to copy entire directory from source to destination as simple Files.copy() will just copy the directory contents not the files withing the directory of given directory [shallow copy].
  2. You can use PathMatcher to match a file. The PathMatcher interface is implemented for each file system, and you can get an instance of it from the FileSystem class using the getPathMatcher() method. Eg .

    String pattern = "glob:File*.java";
    matcher = FileSystems.getDefault().getPathMatcher(pattern);
    System.out.println(matcher.matches(path.getFileName()));

  3. Glob is a pattern-specifying mechanism where you can specify file matching patterns as strings. It's a subset of regex.
  4. postVisitDirectory() will be invoked after all files and directories of a current directory are visited including all files of it's child directories.

 Directory WatchService

By using WatchService you can watch over for changes in files corresponding to a directory. Following program checks if file is changes using WatchService -

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;


public class TestFileWatchService {

    public static void main(String args[]) throws IOException, InterruptedException {
        Path p = Paths.get("C:\\Users\\athakur\\Desktop\\Dir1");
        WatchService ws = p.getFileSystem().newWatchService();
        p.register(ws, StandardWatchEventKinds.ENTRY_MODIFY);
        
        //infinite loop
        while(true)
        {
            WatchKey watchKey = null;
            watchKey = ws.take();
            for(WatchEvent<?> event : watchKey.pollEvents()){
                switch(event.kind().name()){
                    case "OVERFLOW":
                        System.out.println("Some events were lost");
                        break;
                    case "ENTRY_MODIFY":
                        System.out.println("File " + event.context() + " is changed!");
                        break;
                }
            }
            watchKey.reset();//reset the key to get further notifications
        }
    }
    
}

Now try changing any file in the directory you should see output like - 
File File1.txt is changed!
File File1.txt is changed!
File File1.txt is changed!


Few  important points to note here :
  1. You can also create new WatchService using FileSystems.getDefault().newWatchService().
  2. take() method is a blocking call. It will wait till a WatchKey is available where as the poll() method that can also be used to get key is a non blocking call i.e it returns immediately if key is not available.
  3. Once events are polled from the key do not forget to reset the key or else you will not get subsequent event notifications.
  4. Your program may receive an OVERFLOW event even if the path is not registered with some watch service for some events.
  5. Only files in given directory are watched not the ones in subdirectories.
  6. If Path does not correspond to a directory you will get following Exception :

    Exception in thread "main" java.nio.file.NotDirectoryException: C:\Users\athakur\Desktop\abc.txt
        at sun.nio.fs.WindowsWatchService$Poller.implRegister(Unknown Source)
        at sun.nio.fs.AbstractPoller.processRequests(Unknown Source)
        at sun.nio.fs.WindowsWatchService$Poller.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Related Links

Friday, 2 January 2015

Using Memcached with commandline for caching in Java

Background

There are many caching frameworks in Java like EHCache and OSCache. These are essentially in-memory caches. Meaning it uses the same java process memory to cache data. You can imagine them as HashMap or HashTable in your own java program. This frameworks work just fine for caching data in size of few GBs. In this post we will see Memcached which is another caching framework that uses distributed architectural approach as a result of which large amount of data can be stored.



 Memcached Basics

As mentioned in background section memcached uses distributed architectural approach. It is essentially different process (server). Then you have memcached client (essentially jars) that you import in your java program which talks with memcached server. You can have multiple memcached servers . No server is aware of other servers. It is the client that is aware of which server has a particular key stored.

Starting/Stopping Memcached server

You can use following commands in Linux

  • Start Server :  /etc/init.d/memcached start
  • Stop Server : /etc/init.d/memcached stop
  • Restart Server : /etc/init.d/memcachedrestart
  • Check status : /etc/init.d/memcached status 
For windows simply do

  • memcached.exe start
  • memcached.exe stop .... etc
 In windows to install memcached as a service you can do -
  • memcached.exe -d install
Then you can start it from services panel -



To see list of all commands type
  • memcached.exe -help


Go ahead . Play around with the command line. Also if the default port i.e 11211 is used by some other process on your machine change the port of your memcached server.

Note : By default server will start up on port 11211 with 64 MB of memory.

Connecting to Memcached server

You can do telnet to your localhost and port to connect to memcached server. Eg.

C:\Users\athakur\Softwares\memcached>telnet localhost 11211

This will connect to your memcahcahed server. You can type "stats" to get the server statistics like PID of the process, uptime etc

You can type quit to exit from the telnet.



Using command line to get Memcahched details

Memcached puts your data into different "slabs" depending on the data size. This optimized memory allocation and reduces fragmentation. You can see these slabs with command -

  • stats slabs
Another useful command is to find slabs with some data in it. For that you can use
  • stats items
After getting slabs you can get the keys in the slab with following command -
  • stats cachedump [slabID] [number of items, 0 for all items]
For Eg. you can do

stats cachedump 2 0
ITEM TEST_DATA_KEY [16 b; 1420207128 s]
END


This will list down all data items in slab 2. Text following the ITEM keyword is the key of the data. To get the value of the key you can simply do

  • get keyName
Eg. Yo get value for key  TEST_DATA_KEY you have to do

get TEST_DATA_KEY
VALUE TEST_DATA_VALUE 0 68
test_value

END

To delete data by it's key you can simply do
  • delete keyName
 For eg. to delete above data you have to do

delete TEST_DATA_KEY
 DELETED
get
TEST_DATA_KEY
 END

Note the subsequent get call gives nothing as the data is deleted.

You can clear the entire cache with following command
  • flush_all 

Eg.
telnet localhost 11211
flush_all
quit 

Related Links

Sunday, 28 December 2014

Skipping Gradle Tasks

Background

Gradle simply speaking is a build tool like Apache ant but it does more that that and in an efficient way. It handles dependency management as well. You can say -

Gradle = Apapch Ant + Apache Ivy

In the background Gradle is all Groovy.  So if you are aware of groovy writing tasks in gradle is no big deal.

Make sure you have JDK configured and gradle installed.



Gradle Task Build Life Cycle

Gradle has 3 distinct phases -
  1. Initialization
  2. Configuration
  3. Execution

For more details on each of the phases refer Gradle Build Life Cycle . To quickly understand this build life cycle put following code in build.gradle file and run it - 

logger.lifecycle("This is executed during configuration phase");
task A() {
    logger.lifecycle("This is also executed during configuration phase");
    doFirst {
      logger.lifecycle('In task A : This is executed first in the execution phase.')
    }
    doLast {
        logger.lifecycle("In task A :This is executed last in execution phase");
    }    
}


and the output is



Hope you got the idea. Configuration and Execution phases are what we are going to concentrate on.

Lets first see how to write dependents Tasks in gradle.

Writing Dependent Tasks in Gradle


Create a file build.gradle and copy following code in it.

task A(dependsOn: 'B') {
    
    doLast {
        logger.info("In task A");
    }    
}

task B(dependsOn: 'C') {
    doLast {
        logger.info("In task B");
    }
}

task C {

    doLast {
        logger.info("In task C");
    }

}


Above code essentially declares three gradle tasks - A, B and C. Also there are dependencies between them. Notices the dependsOn keyword in bracket. Task A depends on Task B which in turn depends on Task C. Now lets run this. Output is -



Note 1 :

You can also define type of a Task. There are various predefined tasks in gradle. Something like -

task copyFiles(type: Copy, dependsOn: 'SomeAnotherTask') {
    from 'src/main/documentation'
    into 'build/target/documentation'
}


Note 2 :

You can also simply say - 

task A << {
    logger.lifecycle("In task A : Execution phase");
}


The '<<' symbol you see is just a shortcut to execute thing is Execution phase. This defines a task called A with a single closure to execute.

Ok now lets come to the intended purpose of this post which is - how to skip tasks.

Skipping Tasks in Gradle

Goal : Goal is to skip task A and all subsequent tasks that A depends on. Lets say we decide this with a property that we provide to gradle from commandline. Lets call it 'skipA'. If 'skipA' is provided in command line arguments we do not execute any task.

For this lets use onlyIf first.

task A(dependsOn: 'B') {
    onlyIf {
        !project.hasProperty('skipA')
    }
   
    doLast {
        logger.lifecycle("In task A");
    }   
}

task B(dependsOn: 'C') {
    doLast {
        logger.lifecycle("In task B");
    }
}

task C {
    doLast {
        logger.lifecycle("In task C");
    }
}


and the output is




Lets analyze what happened here.Yes Task A was skipped as we intended but what about other tasks they were run.

Don't argue that you can put onlyIf and condition in all tasks :) you are smarter than that!

Note : One important point to note is onlyIf is executed during execution phase and by that time gradle has figured out what all tasks it needs to run. Skipping a single task will not skip the task the skipped task depends on. We need to add skipping logic in configuration phase.

There is another way to do this and that is to set enabled = false; inside a task. This will skip the given task. Also we need two other things.

  1. Implement skipping logic in Configuration phase.
  2. Remove all the tasks that the task to be skipped was depending on (This needs point 1.)

So lets see how can we do that. Copy following code in build.gradle file -

task A(dependsOn: 'B') {
    if(project.hasProperty('skipA')) {
        logger.lifecycle("Skipping Project : " + project.name);
        enabled = false;
        dependsOn = [];
    }
   
    doLast {
        logger.lifecycle("In task A");
    }   
}

task B(dependsOn: 'C') {
    doLast {
        logger.lifecycle("In task B");
    }
}

task C {
    doLast {
        logger.lifecycle("In task C");
    }
}


and the output is


Yes we got what we wanted. Now lets see how we did it.

  • First of all see the if statement in task A. It is outside any doFirst() or doLast() method. This ensures it will be run in configuration phase.
  • Then we checked out condition. If it is true then we set enabled  = false for the task. This will skip task A.
  • To stop other tasks from running that A depends on we removed all those tasks by saying dependsOn = []; Again note this worked because we did it in configuration phase.

Related Links

Friday, 26 December 2014

Suppressed exceptions in java 7

Background

In Java 7 new feature was introduced - try-with-resources statement where resources will be autoclosed. We will come to that. But this feature introduced another important topic and that is suppressed Exceptions and that is what we will discuss in this post.


Suppressed Exception in Java 6

Consider simple try-catch block

public class HelloWorld {

    public static void main(String args[]) {
        try {
            test();
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

    public static void test() throws Exception {
        try {
            System.out.println("In try block");
            throw new NullPointerException("NPE from try block");
        } finally {
            System.out.println("In finally block");
            throw new NullPointerException("NPE from finally block");
        }
    }

}

and the output is : 

In try block
In finally block
java.lang.NullPointerException: NPE from finally block

Where did the NPE thrown from try block go ? Well it was lost or ignored. One dirty way to retain the cause Exception is to chain it. 

To summarize what above part says is that exception thrown from finally block eats up the exception that might have been thrown from try block.

Now lets head over to Java 7 try-with-resource statement to see what it has for us.

Try With Resources statement in Java7

Hope you are aware what try-with-resource statements are. If not please first go through try-with-resource section of Whats new in Java7 post.

As you know resource that can be used in try-with-resource statement needs to implement Closable or AutoClosable interface. Lets define one such resource.

public class DefectiveResource implements AutoCloseable {

    public DefectiveResource() {
        System.out.println("This is defective constructor");
        throw new NullPointerException("From DefectiveResource constructor");
    }

    public DefectiveResource(String str) {
        System.out.println("This is non - defective constructor.");
    }

    public void process() {
        throw new NullPointerException("From DefectiveResource process");
    }

    @Override
    public void close() throws Exception {
        throw new NullPointerException("From DefectiveResource close");
    }

}


Ok we have our resource. Lets go ahead and test it out.


Case 1 : Exception thrown while instantiating a resource

Consider following code - 

public class HelloWorld {

    public static void main(String args[]) {

        try {
            testSuppressException();
        } catch (Exception ex) {
            System.out.println(ex);
        }

    }

    public static void testSuppressException() throws Exception {
        try (DefectiveResource dr = new DefectiveResource()) {
            System.out.println("In testSuppressException");
        }

    }
}


Output would print -

This is defective constructor
java.lang.NullPointerException: From DefectiveResource constructor

meaning try block was not executed. That's right if exception is thrown while creating resources in try-with-resource block try block is not even executed. Don't even bother thinking about closing resource as it was not created in the first place.

Case 2: Exception is thrown from try-with-resource block as well as try block

 This case is a little tricky. When I say Exception is thrown from try-with-resource block it mean exception is thrown during closing of resources. If exception occurs while instantiating resource it will fall under case1. So Exception is thrown while closing resource (which occurs as a part of try-with-resource statement)  and exception is also thrown from try block.

public class HelloWorld {

    public static void main(String args[]) {

        try {
            testSuppressException();
        } catch (Exception ex) {
            System.out.println(ex);
        }

    }

    public static void testSuppressException() throws Exception {
        try (DefectiveResource dr = new DefectiveResource("Test")) {
            System.out.println("In testSuppressException");
            dr.process();
        }

    }

}

And the output is : 

This is non - defective constructor.
In testSuppressException
java.lang.NullPointerException: From DefectiveResource process

Now lets analyze the code. You can see "In testSuppressException" in the output that means instantiating went through. process() method must have thrown Exception and close() method would have too. But we see only Exception thrown by process() method.

That's right Exception thrown while closing resource from try-with-resource statement was suppressed by the Exception from try block. You can get the suppressed Exception as follows - 

public class HelloWorld {

    public static void main(String args[]) {

        try {
            testSuppressException();
        } catch (Exception ex) {
            System.out.println(ex);
            final Throwable[] suppressedException = ex.getSuppressed();
            if(suppressedException.length > 0)
                System.out.println("Suppresed Exception : " + suppressedException[0]);
        }

    }

    public static void testSuppressException() throws Exception {
        try (DefectiveResource dr = new DefectiveResource("Test")) {
            System.out.println("In testSuppressException");
            dr.process();
        }

    }

}


and output is - 

This is non - defective constructor.
In testSuppressException
java.lang.NullPointerException: From DefectiveResource process
Suppresed Exception : java.lang.NullPointerException: From DefectiveResource close

Hope it's clear now that Exception from try block suppressed Exception that occurred from closing resource in try-with-resource statement. 

I will go 2 step ahead and tell you this. Try-with-resource create an implicit finally statement and tries to close resources in it. and this exception is suppressed by exception from try block.

Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed. 

That means if you provide an explicit finally statement that's ok but resources will be closed before this executed. Meaning the implicit finally block I was talking about will be completed before this.

And this brings me to 3rd case.

Case 3 : Exception thrown from explicit finally block with try-with-res statement

So if Exception is thrown from try-with-resource block (during close), it is also thrown from try block and then again from finally block - 


public class HelloWorld {

    public static void main(String args[]) {

        try {
            testSuppressException();
        } catch (Exception ex) {
            System.out.println(ex);
            final Throwable[] suppressedException = ex.getSuppressed();
            if(suppressedException.length > 0)
                System.out.println("Suppresed Exception : " + suppressedException[0]);
        }

    }

    public static void testSuppressException() throws Exception {
        try (DefectiveResource dr = new DefectiveResource("Test")) {
            System.out.println("In testSuppressException");
            dr.process();
        }finally {
            throw new NullPointerException("From explicit finally block");
        }

    }

}

and the output here is - 

This is non - defective constructor.
In testSuppressException
java.lang.NullPointerException: From explicit finally block

Lets go step by step. Resource instantiation went through. Exception is thrown from try block and then while closing (from implicit finally block if you are imagining that way). So far as per above case exception from try block takes precedence and suppressed exception occurring from close() in try-with-resource statement. But when explicit finally block is executed it again ignores all these exceptions and throws it's own (similar to Java 6 example at the top).

Also if exception was thrown while creating/instantiating resources as in case 1 then try block will not be executed and again exception from explicit finally block would override this.

Bottom line : If your explicit finally block throws Exception all your previous exceptions are eaten up.

Important point of this post was to explain that the Exception from close() is suppressed by Exception from try block.

Note : The close methods of resources are called in the opposite order of their creation.

Related Links




Saturday, 20 December 2014

CodeChef problem

Question : 


STATEMENT

There are n events. Each has a start time and end time. You wish to attend maximum of such events.

NOTE:If start time of one event is same as end time of other you cannot attend both. You can imagine some time to travel from event1 to event2.

INPUT

The first line will contain an integer T, denoting the number of test cases.

Each test case contains several lines.

The first line of each test case will contain an integer N, denoting the number of events.

The next N lines, one for each event, contain two space separated integers, starttime and endtime.

1 <= T <= 10
1 <= N <= 10000
0 <= starttime < endtime <= 1000000000

OUTPUT

For each test case, output a single integer denoting the maximal number of events that you can attend.
EXAMPLE
INPUT

2
5
0 5
0 2
3 5
3 4
5 6
6
0 8
8 10
11 12
11 15
2 5
7 9
OUTPUT

3
3
EXPLANATION

In the first case you can attend events (0, 2), (3, 4), (5, 6)



Solution


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

/**
 * 
 * @author athakur
 *
 */
public class Quark1 {

    public static void main(String args[]) throws IOException {
        
         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
         PrintWriter writer = new PrintWriter(System.out,true);
        
         int noOfTestCases = Integer.parseInt(reader.readLine());
        
         for(int i=0; i<noOfTestCases; i++) {
             int noOfEvents = Integer.parseInt(reader.readLine());
             Event[] events = new Event[noOfEvents];
             for(int j=0; j< noOfEvents; j++) {
                 String[] times = reader.readLine().split(" ");
                 events[j] = new Event(Integer.parseInt(times[0]),Integer.parseInt(times[1]));
             }
             writer.println(getMaxEvents(events));
         }
    }
    
    private static int getMaxEvents(Event[] events) {
        Arrays.sort(events);
        int i=0;
        int count = 1;
        for (int j=1; j<events.length;j++) {
            if(events[j].startTime > events[i].endTime) {
                count++;
                i=j;
            }
        }
        return count;
    }
    
    static class Event implements Comparable<Event>
    {
        int startTime;
        int endTime;
        
        public Event(int startTime, int endTime) {
            this.startTime = startTime;
            this.endTime = endTime;
        }

        @Override
        public int compareTo(Event event) {
            return this.endTime > event.endTime ? 1 : (this.endTime < event.endTime ? -1 : 0);
        }
    }
    
}
 

Explanation : 

First we sort the events based on the finish time because we want to attend earliest events first. Now if end times if two events are same we can attend either. So we don't bother about it. On sorting such events can have sequential positioning (one after the other) in either way. Next we start from first event in sorted events list. We can only attend next event if it's start time is greater (mind even equals will not work as we have to consider commute delay) than the end time of current event. Current event is tracked with i variable where as next event is tracked with j.

t> UA-39527780-1 back to top