0

I have an issue reported by an user which I cannot reproduce. The issue is error:

Exception in thread "main" java.lang.NullPointerException: source at java.util.Objects.requireNonNull(Unknown Source) at java.util.Scanner.(Unknown Source) at cz.autoclient.Main.getVersion(Main.java:86) at cz.autoclient.Main.(Main.java:76) at cz.autoclient.Main.main(Main.java:262)

In this code:

   private VersionId VERSION = new VersionId("0.0-error");
   public final VersionId getVersion() {
     if(VERSION.affix.equals("error")) {
       InputStream in = Main.class.getResourceAsStream("/version");
       Scanner sc = new Scanner(in, "UTF-8"); // LINE 86
       VERSION = new VersionId(sc.useDelimiter("\\A").next());
     }
     return VERSION;
   }

What I do here is to parse internal resource which contains version info for the application (including version as variable turned out to be very impractical).

Version file might look something like this:

v3.5-beta

The error seems to be caused by the resource "/version" being unreachable. This error does only seem to happen to the user, so I need help why it even might happen. User's Java version is:

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Here is the full Main.java (specific commit). The application is distributed as jar file. The version file is in the root of the jar file.

In case it happened to be unclear the problem is when I run the same release (downloaded from release site, not re-built), I do not encounter the problem. I asked the user to verify that the file is there (by unziping the jar file). He sent it to me, it was intact.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • 2
    Pretty obvious: Something's `null`, probably `in`. Have you tried `getClassLoader().getResourceAsStream("/version")`? – chrylis -cautiouslyoptimistic- Aug 22 '16 at 11:22
  • @xenteros Are you serious or trolling? Does this seem like a generic null pointer exception problem to you? – Tomáš Zato Aug 22 '16 at 11:22
  • I think it means that the InputStream you pass to the Scanner can't be null, but it is because that Resource isn't available. Check your assumptions. – duffymo Aug 22 '16 at 11:22
  • 1
    He's serious because this *is* a run-of-the-mill NPE. There's an obvious spot for the null to show up, and you haven't explained what you tried there. I refrained from going Mjollnir only because I've encountered you personally before. – chrylis -cautiouslyoptimistic- Aug 22 '16 at 11:22
  • @duffymo Thanks for the input. But my main problem is why does it even happen. If I add null check, it doesn't solve the problem, my program will still have no idea what the version is... Not mentioning that I CANNOT reproduce it on my PC. – Tomáš Zato Aug 22 '16 at 11:23
  • 2
    Why? That's obvious, too: the assumption you make about the existence of that Resource or the path to find it are incorrect. – duffymo Aug 22 '16 at 11:24
  • @chrylis Not it is not, because even if I add null check, the problem will not be solved. Also, typical run-of-the-mill problems can be reproduced, I failed to reproduce this with exactly the same files as the user has. – Tomáš Zato Aug 22 '16 at 11:24
  • @TomášZato are you sure the `version` file is in the JAR you shipped to that customer? – Vampire Aug 22 '16 at 11:26
  • @TomášZato you mean to say that even after adding `in != null` check, the NPE still occurs? – Dakshinamurthy Karra Aug 22 '16 at 11:27
  • 2
    @KDM no, he said that in must not be null as the `version` file should be part of his JAR. – Vampire Aug 22 '16 at 11:28
  • @KDM No, I mean that preventing the exception doesn't sovle the problem. If the exception is ignored, caught or prevented, the problem will still be, which is unreachable resource, which only happens on user's PC. I was hoping I could get help with guessing what the problem is, but SO is too corrupted by answering simple code questions to get any real help here. – Tomáš Zato Aug 22 '16 at 11:29
  • @Vampire I said I ran the exactly same file as he did... How to make it even more clear? – Tomáš Zato Aug 22 '16 at 11:29
  • If `getResourceAsStream()` returns `null` it means the resource can't be found. How could we have any idea what might go wrong without even knowing your applications structure - how is it shipped, where should `version` be etc. so as it is the question is either way too broad or totally unanswerable. – piet.t Aug 22 '16 at 11:30
  • You didn't say, for example, *how* it was run. If this is a war file, for example, it's entirely possible for the classloader structure to differ between container configurations, which would cause this problem. – chrylis -cautiouslyoptimistic- Aug 22 '16 at 11:30
  • @TomášZato I'm sorry that I don't reload after each typed character to not miss a comment where you add new information. Go to a behaviour class and solve your problems on your own until then. I'm out here, I don't like helping rude people. – Vampire Aug 22 '16 at 11:32
  • 1
    The resource file (in the jar) must be at the root and be named "version", case-sensitive and without extensions. There might have been an extension, that Windows did not display, but more likely the file on the file system is call Version with big V. – Joop Eggen Aug 22 '16 at 11:32
  • @JoopEggen Those are good points but I checked and the file is exactly as you described. Again, when I run it, it works, but user reports this error. I asked him to re-download from specific link to make sure we're using same release. – Tomáš Zato Aug 22 '16 at 11:36
  • One debugging step that's a long shot but might help is to log *the actual value of `getClassLoader()`*. It'll tell you the actual implementing class, which might possibly yield a useful distinction. – chrylis -cautiouslyoptimistic- Aug 22 '16 at 11:41

2 Answers2

1

Evidently you ran the code in your IDE, which doesn't use the built JAR file at all: it uses the directory hierarchy produced by the compilation step. All you you have to do here is check the content of the JAR file you shipped, which obviously does not contain /version. The way to reproduce this problem is to run the same JAR file the same way the customer did, in a clean install. However that's not what you're really asking. The solution is to get rid of the resource, and put the version information into the JAR manifest, where you can't forget to ship it.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks for recommending the jar manifest, I will look into that. Otherwise, I am surprised by your confidence. I downloaded the same release. It's written in my question, I will edit it to make it clear that I ran the built version. – Tomáš Zato Aug 22 '16 at 11:54
  • I asked the user to verify that the file is there. He sent it to me, it was intact. – Tomáš Zato Aug 22 '16 at 12:12
0

User claims that he uninstalled MacAfee antivirus (distributed with their PC) and replaced it with Avast! and that this fixed the problem. Not exactly a programming answer but I decided to share this in case someone faces the same problem.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778