Android file is and isn't null - java

That is the best way in which I can describe what's going on.
This is my line of code:
if (offer.getFamily().getProfileImage() == null)
And this is what the debugger is showing:
Both offer and family aren't null.
So instead of going inside the if like it should it tries to get the file path and of course it fails with a NullPointerException.
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.isEmpty()' on a null object reference
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:95)
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:130)
at java.io.File.getAbsolutePath(File.java:524)
at com.yournanny.utilities.ProfileImageUtilities.showProfileImage(ProfileImageUtilities.java:109)
Here is where I get the error:
public static void showProfileImage(User user, ImageView image) {
image.setImageBitmap(BitmapFactory.decodeFile(user.getProfileImage().getAbsolutePath()));
}
What is going on here?
Update
Looking at the comments I broke the chains and re-run it, neither offer or getFamily() return null, if I call other method over them I get the expected values.
But getProfileImage() is definitely returning null, the problem is that somehow it isn't null enough when I compare it in the if.
But on calling getProfileImage().getAbsolutePath() I get this:

Well apparently the problem was with the deserialization of the offer (and particularly of the family inside of it).
I was getting offer through a retrofit get call.
I added transient to the profileImage attribute and this fixed the problem:
private transient File profileImage;
Now this is what the debugger shows:
So I'm guessing gson (I'm using it to deserialize the retrofit responses) was creating a file without a assigning it a path and that's why it was and wasn't null.
But a proper explanation would be great.

The File was non-null but its name was null internally.

Related

looking for the reason for NPE in LinuxNetworkParams.getDomainName call

We are seeing the NPE in the LinuxNetworkParams.getDomainName call in oshi version 6.1.6. Although I am not able to see any reason for this. Can anyone help me when with the reasons why this can throw NPE?
Caused by: java.lang.NullPointerException
at oshi.software.os.linux.LinuxNetworkParams.getDomainName(LinuxNetworkParams.java:80) ~[oshi-core-6.1.6.jar!/:6.1.6]
at com.airwatch.common.diagnostics.DiagnosticCollector.fetchSystemConfiguration(DiagnosticCollector.java:148) ~[diagnostic-library-2.0.3.jar!/:?]
Here is the code for the method :
https://github.com/oshi/oshi/blob/oshi-parent-6.1.6/oshi-core/src/main/java/oshi/software/os/linux/LinuxNetworkParams.java#L79-L80
Looks like info.ai_canonname is null, Try adding null check for ai_canonname or use null safe way to do trim like StringUtils.trim()
public static String trim(final String str) {
return str == null ? null : str.trim();
}
As #Jishnu-Prathap said in their answer, info.ai_canonname is null.
This value normally returns the "official name of the host" in response to the getaddrinfo() function whose docs state:
If hints.ai_flags includes the AI_CANONNAME flag, then the ai_canonname field of the first of the addrinfo structures in the returned list is set to point to the official name of the host.
This may represent an error in your server configuration; fixing the "official name of the host" will prevent the NPE if you keep the same OSHI version.
However, failing to null-check this value was a bug in earlier versions of OSHI but was fixed in version 6.2.2 and upgrading will also prevent the NPE (but not give you a canonical host name, since it doesn't exist!)

How to use String ressource in Java file in Android without a Layout

I have a Java class that mainly contains strings. It does not have a layout as it is neither a Fragment nor an Activity. It is more used as an auxilliary class. I would like to assign the String values in the class by using the Resource strings as I would like to automatically translate the Strings. Howvever, I can't access the string resources from Java. I use the following code:
static String more = getString(R.string.more);
And in the XML file I have the ressource:
<string name="more">More</string>
I get the error message
Cannot resolve method 'getString'
I also tried static String more = getContext().getString(R.string.more);
but I got the error message:
Cannot resolve method 'getContext'
Would anyone mind helping me on that? I'd appreciate every comment.
Update: I tried to use the answer from "MikaelM"
Resources.getSystem().getString(R.string.more)
However, I get an "exception in initializer error" and when I use the initial String again, I do not get this error. So I still can't get the String from the ressource. DO you have an idea what I can do? I'd appreciate every further comment.
So the error is caused by "Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f120038"
The strange thing is that the resource in fact exists (I checked this several times).
getString(R.string...
is not the same as
Resources.getSystem().getString(android.R.string...
Only the second variant you can use in the static context. Alas, you can get this way only system resources.
If you need to get your own resources, no one-line solution exists. Use https://stackoverflow.com/a/4391811/715269 solution of #Cristian. And notice: it is a very good solution, even more, it is the solution meant to be used by the creators of Android.
You should be able to get your string with:
Resources.getSystem().getString(R.string.more)
See more here, getString Outside of a Context or Activity

Fortify Finding: Null Dereference

I have read a bunch of the other Fortify null de-reference questions here, but none of them apply or seem to be as basic as the one our project incurred. While scanning this block of code:
private GenderCode gender;
.
.
.
if (gender != null) {
subject.setGender(gender.getName());
} else {
subject.setGender(null);
}
Fortify flags subject.setGender(null) as a possible null de-reference. This makes absolutely no sense to me -- all we are doing is explicitly setting a value to null. Note that in the local class, gender is of type GenderCode and in the subject class, gender is a String.
The original code we had:
subject.setGender(gender != null ? gender.getName() : null);
was also flagged. What variable is possibly being de-referenced here? We're only setting an attribute on another object to null! Perfectly legal. Further, the code specifically sets the value to null within an if-then-else block which should indicate to Fortify that, yes, we are doing this on purpose -- we are aware that we are setting gender (a String attribute on the subject object) to null. Why does this get flagged and is there a simple, non-convoluted solution that appeases the Fortify gods?

Play 2.5: Form validation - on error, value of form is "Optional.empty"

I am developing an application with Play 2.5. Models and Form data are separate classes, so I have a class "Page" and "PageForm".
In PageForm is a method "validate()" which returns null if there was no error or a List if the validation failed:
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<>();
Page checkForDuplicatePage = PageRepository.getInstance().getByName(name);
if(checkForDuplicatePage != null && checkForDuplicatePage.id != id) {
errors.add(new ValidationError("name", "The name is already in use by another page"));
}
// ...
return errors.isEmpty() ? null : errors;
}
In my controller I call:
Form<PageForm> form = formFactory(PageForm.class).bindFromRequest();
This works really well if the data in the form is correct. However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this), the "value" attribute of my form is Optional.empty. The "data" attribute actually has all the data passed to the form.
This means I can't use the form to pass it to my view, which should display the data with error messages. Instead I get a [CompletionException: java.util.NoSuchElementException: No value present]. Sometimes (I haven't figured out why that happens yet) it also says [CompletionException: java.util.NoSuchElementException: None.get].
I compared my code with other projects and the official docs, but they all seem to be doing what I have here.
I use Scala Play rather than Java, so YMMV. But to me, I don't think that validate should return null at all. It should return the empty ArrayList if there are no errors. I suspect that this will eliminate the None.get error message. I'm not sure how much I can help, though, because I don't really understand very well what your code is intended to do. For example, the sentence
However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this)
seems kind of ambiguous to me. Where is the return new ArrayList<>() call that triggers the error?

Java Enum Returns Null

I am currently creating a plugin for Minecraft using the SpigotAPI. Reason I'm posting this here is because this I believe is a Java error. I am creating a duels plugin where inside my code it'll loop through an enum, and see if it's a specific type. The first time using it around it properly works, no problems. But when I try it for a second time without restarting my plugin/program/code it'll return the enum as null. Here is the code, is there a fix to this?
public DuelArenas[] getArenasWithType(DuelTypes type) {
String suffix = "_NORMAL";
List<DuelArenas> arenasAsList = new ArrayList<>();
switch (type) {
case NORMAL:
suffix = "_NORMAL";
break;
}
for (DuelArenas arena : duelArenaStatus.keySet()) {
if (arena.toString().endsWith(suffix)) {
arenasAsList.add(arena);
}
}
DuelArenas[] arenas = new DuelArenas[arenasAsList.size()];
return arenasAsList.toArray(arenas);
}
Stacktrace:
Caused by: java.lang.NullPointerException
at me.nick.acore.duels.DuelsAPI.getArenasWithType(DuelsAPI.java:97) ~[?:?]
And yes I've checked to see if the enum was null, and it was in fact null. Also line 97 is
if (arena.toString().endsWith(suffix)) {
And finally here is the DuelArena class
public enum DuelArenas {
ARENA_1_NORMAL, ARENA_2_NORMAL, ARENA_3_NORMAL, ARENA_4_NORMAL, ARENA_5_NORMAL,
ARENA_6_NORMAL, ARENA_7_NORMAL, ARENA_8_NORMAL, ARENA_9_NORMAL, ARENA_10_NORMAL,
ARENA_11_NORMAL, ARENA_12_NORMAL }
Thanks!
Your problem is that you cannot directly convert your custom DuelArenas class to a string. However when you are comparing to see if a .toString() ends with suffix, I feel that something is also going wrong. You would only ever use .toString to convert things like numbers to strings, and if your are converting a number to a string there is no way it will end in _NORMAL.
So if you want me to troubleshoot further please post your DuelArenas class, but until then my best guess is that when you do arena.toString you are looking to pull some sort of value from that class that is stored in it, and to do this you would do arena.variableInsideArenaName and work with that.
EDIT:
After seeing the class scratch that, the error in going to be somewhere in this line DuelArenas arena : duelArenaStatus.keySet()

Categories