0

I'm trying to make the Google Drive Java Quickstart work, but I'm stuck with a NullPointerException when trying to use the InputStream.

Google's quickstart code

InputStream in =
            Quickstart.class.getResourceAsStream("client_secret.json");
        GoogleClientSecrets clientSecrets =
            GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

According to one SO question, the getResourceAsStream looks for the file in the same directory as the class calling it, so I put my client_secret.json with my class:

|src/main/java
|---quickstart
|------Quickstart.java
|------client_secret.json

I still have the NullPointerException, so I tried to create the InputStream from a File instead of using getResourceAsStream:

java.io.File initialFile = new java.io.File("A:/Documents/client_secret.json");
//   java.io.File initialFile = new java.io.File("client_secret.json");
if (initialFile.canRead()) {
    System.out.println("it works!");
} else {
    System.out.println("that's a fail");
}
System.out.println(initialFile.getAbsolutePath() + " " + initialFile.exists() + " " + initialFile.getAbsoluteFile().exists());
InputStream in = new FileInputStream(initialFile);

which results in:

that's a fail
A:\Documents\client_secret.json false false
Exception in thread "main" java.io.FileNotFoundException: A:\Documents\client_secret.json (Le fichier spécifié est introuvable)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at quickstart.Quickstart.authorize(Quickstart.java:76)
    at quickstart.Quickstart.getDriveService(Quickstart.java:102)
    at quickstart.Quickstart.main(Quickstart.java:111)

I can find the files when I use the path in my explorer.

I've tried different ways to open the file (absolute path, relative path, using "parent" constructor, ...), but always the same result. This code works when I execute it on online java compilers though (like tutorialspoint's one).

My OS is Windows 10, I'm working with Eclipse IDE.

Carrm
  • 1,485
  • 3
  • 24
  • 45
  • 1
    `A:\Documents`? – Jens Apr 27 '17 at 09:21
  • The duplicate explain the difference between `"/client_secret.json"` and `"client_secret.json"` – AxelH Apr 27 '17 at 09:21
  • remove the slash here: `Quickstart.class.getResourceAsStream("client_secret.json");` – Jens Apr 27 '17 at 09:22
  • @Jens I duplicated my file on different places (A:\Documents, with Quickstart.java etc) – Carrm Apr 27 '17 at 09:22
  • 1
    What drive is A? Normally i know it as floppy disk drive ( from a Long time ago) – Jens Apr 27 '17 at 09:23
  • A:/Documents is only my last try. I tested on C: and other partitions (A: is one of them). For the slash in the getResourceAsStream part, it's my mistake: I copied this code from the tutorial, but in my code I've already removed it. – Carrm Apr 27 '17 at 09:30
  • (and the down vote is harsh as I DID make a research effort and my question seems clear. I've posted this because I couldn't find anything useful/working in other SO questions, or in the web...) – Carrm Apr 27 '17 at 09:33

1 Answers1

0

This is explain in the complete answer of LordOfThePigs.

In Class.getResourceAsStream(path), the path is interpreted as a path local to the package of the class you are calling it from. For example calling, String.getResourceAsStream("myfile.txt") will look for a file in your classpath at the following location: "java/lang/myfile.txt". If your path starts with a /, then it will be considered an absolute path, and will start searching from the root of the classpath. So calling String.getResourceAsStream("/myfile.txt") will look at the following location in your class path ./myfile.txt.

Your path is defined like an absolute one, absolute to the root of the classpath.

Quickstart.class.getResourceAsStream("client_secret.json"); // remove the "/"

Example

- src
    - labo
        - Main.java
        - Test.log // > Hello from Labo
    - Test.log // > Hello from Source Package

This will be the output based on the path

InputStream in = Main.class.getResourceAsStream("Test.log"); //   /labo/Test.log
// > Hello from Labo
InputStream in = Main.class.getResourceAsStream("/Test.log"); //  /Test.log
// > Hello from Source Package

Code :

public class Main {
    public static void main(String[] args ) throws Exception{
        String[] paths = {"/Test.log", "Test.log"};
        for(String path : paths)
            readPath(path);
    }

    static void readPath(String path) throws Exception{
        InputStream in = Main.class.getResourceAsStream(path);
        InputStreamReader reader = new InputStreamReader(in);
        int i = -1;
        System.out.println(path + " : ");
        while((i = reader.read()) > -1){
            System.out.print((char)i);
       public }
        System.out.println();
    }
}

Output :

/Test.log : 
Hello from the Source Package
Test.log : 
Hello from Labo
Community
  • 1
  • 1
AxelH
  • 14,325
  • 2
  • 25
  • 55
  • As I said in the comments, the slash was a copy/paste mistake (copied from the actual quickstart, but already removed in my code). I edited the original post – Carrm Apr 27 '17 at 09:43
  • @Carm provide an example to reproduce this. I did create my example to confirm this, it is working. And here is the full example – AxelH Apr 27 '17 at 09:50
  • Well, I guess that my problem must come from somewhere else, as I can't make your example work (NullPointerException)... – Carrm Apr 27 '17 at 10:11
  • @Carrm So the `inputstream` is null ? _A InputStream object or null if no resource with this name is found_ Clean the project and try again. I don't see a solution for this – AxelH Apr 27 '17 at 10:13
  • Yes, looks like it is null – Carrm Apr 27 '17 at 10:15
  • @Carrm How are you running the project ? – AxelH Apr 27 '17 at 10:41