This is my code. It thinks that the config area section = null.
Heres the code:
public void loadArenas() {
fc1 = new File(plugin.getDataFolder(), "config.yaml");
if (!fc1.exists()) {
try {
fc1.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
fc = YamlConfiguration.loadConfiguration(fc1);
for (String keys : fc.getConfigurationSection("Arenas.").getKeys(false)) {
Oh and heres the error:
Error
fc1 is initialized, but fc is not.
You should print out the contents of fc1 at the top. It is very likely that you are running into path-related issues and so a new, EMPTY, configuration file is created.
That new file is then used as the input to fc, and naturally the "Arenas." section wouldn't exist. The NPE would either be thrown when you try to access the non-existent section's keys via getKeys().
Either way, if you are not sure what the problem is, you can either step through it with a debugger or just throw print statements everywhere to determine that things are what you expect.
Related
Summary
I am looking at a scenario, such as this:
File someFile = null;
try
{
someFile = File.createTempFile( SOME_PREFIX, SOME_SUFFIX, targetDirectory );
}
catch( IOException e )
{
throw new SomeException( "Unable to create file for domain specific task", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
try( BufferedOutputStream stream = new BufferedOutputStream( new FileOutputStream( someFile.getAbsolutePath() ) ) )
{
stream.write( byteData, 0, byteData.length );
stream.flush();
}
catch( IOException e )
{
throw new SomeException( "Unable to write domain specific data to domain specific file", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
For this scenario someFile is initialized with null. My intent is to translate this code into something that follows proper practices.
What I considered
Simply initializing someFile to null, as shown in the current code snippet. However typically I am avoiding this, so this does not seem satisfactory as of now
Initializing someFile with e.g. an empty String. This provides a default instance of File of sorts. The problem I see with this is, if this error handling changes in the future, a valid File with nonsense properties could be passed to some other place inside the code.
Nesting the try-catch blocks. This does work, however for some reason feels bad, especially since both nested blocks catch IOException
An Optional<File> was also considered, I am however not convinced if every try-catch block where a somewhat complex object is initialized to be used outside that block justifies the use of Optional
Question
Is initializing someFile to null an antipattern? If so, how is a scenario, such as the one posted, handled best?
How about something like this:
public void yourMethod() {
File file = createFile();
writeFile(file);
}
private File createFile() {
try {
return File.createTempFile(...);
} catch(...) {
...
}
}
private void writeFile(File file) {
try(...) {
...
} catch(...) {
...
}
}
So your method stays clean and easy to understand.
EDIT: Or even return an Optional<File> from createFile:
private Optional<File> createFile() {
try {
return Optional.of(File.createTempFile(...));
} catch(...) {
...
return Optional.empty();
}
}
Then you can use Optional.ifPresent in yourMethod:
public void yourMethod() {
Optional<File> file = createFile();
file.ifPresent(value -> writeFile(value));
// or shorter:
createFile()
.ifPresent(this::writeFile);
// depends on how exactly the methods receive their parameters
}
You can just have
File someFile;
without any explicit assignment.
Java would then normally complain about using that variable before it has a value but the compiler is smart enough to understand that the only way the variable might not have a value is if createTempFile throws an IOException, but since you catch that and then throw again it knows that either the method exits here or someFile has a proper value. Therefore the later usages of someFile.getAbsolutePath() are allowed.
This is cleaner than null because now if you e.g. remove the re-throwing of the exception your code will not longer compile because now the compiler can no longer infer a value will always be assigned. If you init with null and remove the re-throw you will run into an NPE later on.
Optionals are not needed here because the compiler can in this case differentiate between non-initialized value and initialized value.
I'm working on a program that uses JavaFx to display icons in a list.
I've made a static class used to look up specific ids from a txt document. Originally, the static block would add the id and name of an item defined on each line, but since these issues arose, I've tried to find the source of the issue.
Instead, I've just gone through the text file's content in the static block and have printed it out to the console.
This is my code for reference:
public class ItemIds {
public static int UNDEFINED_ID = -1;
private static HashMap<String, Integer> items;
static {
items = new HashMap<String, Integer>();
System.out.println(new File("res/ids/item ids.txt").exists());
try {
//should print out every line in the text file
Files.lines(Paths.get("res/ids/item ids.txt")).forEach(s -> {
System.out.println(s);
});
} catch (IOException e) {
System.out.println("Unable to read specified file.");
e.printStackTrace();
}
}
public static int getId(final String name) {
final Integer id = items.get(name);
return id != null ? id : UNDEFINED_ID;
}
}
However, what I do get when this static class is initialized and the static block is invoked is quite odd. It lists every single line without error until it gets to line 10691, where it throws "Exception in thread "JavaFX Application Thread" java.lang.ExceptionInInitializerError".
What makes this particularly weird, however, is that when I work with a smaller text document (with less entries), everything seems to work fine. Since the file is comprised of almost 14000 lines, I have to delete ~4000 lines for it to be able to work.
Any ideas on why it would be doing this? Any feedback is appreciated - thank you
I am unable to reproduce this error. I have created a file with 18K lines and you program just works fine with that. So, definitely consider reviewing your file and also the stack trace.
Now coming back to your exception ExceptionInInitializerError, the following is a possible:
ExceptionInInitializerError signals that an unexpected exception has occurred in a static initializer. An ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer or the initializer for a static variable.
class ItemIds
{
static
{
// if something does wrong -> ExceptionInInitializerError
}
}
Because static variables are initialized in static blocks there is a potential for introducing errors too. An example:
class ItemIds
{
static int v = D.foo();
}
=>
class ItemIds
{
static int v;
static
{
v = D.foo();
}
}
So if foo() goes crazy then you can get a ExceptionInInitializerError.
Have you presented your complete code in static block?
I've been trying to find a good solution to this problem for 2 hours, but I haven't found anything useful.
I have method that gets IssueData from mantisApi for use later in the code. It also catches any exceptions thrown:
try {
IssueData issue = mantisApi.getIssue(issueId, user);
task = prepareMantisTask(issue);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return task;
The problem is when I get the IssueData I expect null because it might be an empty field. However when it returns, an exception is caught in this try/catch block. I tried to ignore using the following code:
public String getProjectNotNull(MantisTask mantisTask) {
if (mantisTask == null){
return null;
}
try{
String project = mantisApiCache.getProject(mantisTask.getProject()).getName();
return project;
}
catch(NullPointerException npe){
log.info("TaskService.getProjectNotNull() throws controled null");
return "-";
}
But it looks stupid when I have 20 or more records to check. Is there any other way to ignore nulls? Thank you for your time.
I'm sorry I'm at home now, and i cannot copy code.
prepareMantisTask looks like:
MantisTask mantisTask;
mantistask.setId = issue.getId();
so example. if i do mantistask.setDueData = issue.getDueData(); it is null because not all issues have this parameter. So when the debugger get to this point, it returns to
} catch (Exception e) {
System.out.println(e.getMessage());
}
and left prepareMantisTask with task null.
This two pieces of code are from different parts of my program, I just wanted to show how it works.
Why not just make a null check instead of waiting for an exception?
Perhaps something like this:
public String getProjectNotNull(MantisTask mantisTask) {
if (mantisTask == null){
return null;
}
String project = "-";
// check whatever may be null here
if (mantisTask.getProject() != null
&& mantisApiCache.getProject(mantisTask.getProject()) != null) {
project = mantisApiCache.getProject(mantisTask.getProject()).getName();
} else {
log.info("TaskService.getProjectNotNull() throws controled null")
}
return project;
}
EDIT
In response to your edit, the rule still maintains though. If not all issues have that parameter, you must check it before, so that you never get exceptions because something is null.
Assuming the null pointer exception is due to issue.getDueData(), you likewise do:
if (issue.getData() != null) {
mantistask.setDueData = issue.getDueData()
}
so that you'll never get a null pointer exception in the first case.
In short, there is no way to ignore nulls, you must check each one of them before using them (and never relying on exceptions to check for nulls).
I have the following code:
TestClass test=new TestClass();
test.setSomething1(0); //could, but probably won't throw Exception
test.setSomething2(0); //could, but probably won't throw Exception
I would like to execute: test.setSomething2(0); even if test.setSomething(0) (the line above it) throws an exception. Is there a way to do this OTHER than:
try{
test.setSomething1(0);
}catch(Exception e){
//ignore
}
try{
test.setSomething2(0);
}catch(Exception e){
//ignore
}
I have a lot of test.setSomething's in a row and all of them could throw Exceptions. If they do, I just want to skip that line and move to the next one.
For clarification, I don't care if it throws an Exception, and I can't edit the source code of the code which throws this exception.
THIS IS A CASE WHERE I DON'T CARE ABOUT THE EXCEPTIONS (please don't use universally quantified statements like "you should never ignore Exceptions"). I am setting the values of some Object. When I present the values to a user, I do null checks anyway, so it doesn't actually matter if any of the lines of code execute.
try {
// Your code...
} catch (Exception ignore) { }
Use the word ignore after the Exception keyword.
There is no way to fundamentally ignore a thrown exception. The best that you can do is minimize the boilerplate you need to wrap the exception-throwing code in.
If you are on Java 8, you can use this:
public static void ignoringExc(RunnableExc r) {
try { r.run(); } catch (Exception e) { }
}
#FunctionalInterface public interface RunnableExc { void run() throws Exception; }
Then, and implying static imports, your code becomes
ignoringExc(() -> test.setSomething1(0));
ignoringExc(() -> test.setSomething2(0));
IntelliJ Idea IDE suggests to rename a variable to ignored
when it isn't used.
This is my sample code.
try {
messageText = rs.getString("msg");
errorCode = rs.getInt("error_code");
} catch (SQLException ignored) { }
Unfortunately no, there isn't, and this is by intention. When used correctly, exceptions should not be ignored as they indicate that something didn't work and that you probably shouldn't continue down your normal execution path. Completely ignoring exceptions is an example of the 'Sweep it under the rug' anti-pattern, which is why the language doesn't support doing so easily.
Perhaps you should look at why TestClass.setSomething is throwing exceptions. Is whatever you're trying to 'test' really going to be valid if a bunch of setter methods didn't work correctly?
You can't ignore exception in Java. If a method declares being able to throw something this is because something important can't be done, and the error can't be corrected by the method designer. So if you really wan't to simplify your life encapsulate the method call in some other method like this :
class MyExceptionFreeClass {
public static void setSomething1(TestClass t,int v) {
try {
t.setSomething1(v);
} catch (Exception e) {}
public static void setSomething2(TestClass t,int v) {
try {
t.setSomething2(v);
} catch (Exception e) {}
}
and call it when you need it:
TestClass test=new TestClass();
MyExceptionFreeClass.setSomething1(test,0);
MyExceptionFreeClass.setSomething2(test,0);
You should not ignore Exceptions. You should handle them. If you want to make your test code simple, then add the try-catch block into your functions. The greatest way to ignore exceptions is to prevent them by proper coding.
I know this is old, but I do think there are occasions when you want to ignore an exception. Consider you have a string that contains a delimited set of parts to be parsed. But, this string can sometimes contain say, 6 or 7 or 8 parts. I don't feel that checking the len each time in order to establish an element exists in the array is as straight forward as simply catching the exception and going on. For example, I have a string delimited by '/' character that I want to break apart:
public String processLine(String inLine) {
partsArray = inLine.split("/");
//For brevity, imagine lines here that initialize
//String elems[0-7] = "";
//Now, parts array may contains 6, 7, or 8 elements
//But if less than 8, will throw the exception
try {
elem0 = partsArray[0];
elem1 = partsArray[1];
elem2 = partsArray[2];
elem3 = partsArray[3];
elem4 = partsArray[4];
elem5 = partsArray[5];
elem6 = partsArray[6];
elem7 = partsArray[7];
catch (ArrayIndexOutOfBoundsException ignored) { }
//Just to complete the example, we'll append all the values
//and any values that didn't have parts will still be
//the value we initialized it to, in this case a space.
sb.append(elem0).append(elem1).append(elem2)...append(elem7);
//and return our string of 6, 7, or 8 parts
//And YES, obviously, this is returning pretty much
//the same string, minus the delimiter.
//You would likely do things to those elem values
//and then return the string in a more formatted way.
//But was just to put out an example where
//you really might want to ignore the exception
return sb.toString();
}
Those who write empty catch blocks shall burn in the Hell for the eternity.
Or worse, they will be forced to debug the damn rubbish they wrote forever and ever.
That said, one thing you might want to do is writing exception handling in a less verbose way. The NoException library is very good at that.
I'm having trouble opening a file. The hasNext seems to crashing with the following error java.lang.NullPointer. This is my the code that's erring out (with hasNext).
import java.io.*;
import java.util.Scanner;
public class Customers{
private Scanner opener;
public void openFile() {
try {
opener = new Scanner (new File ("customer.txt"));
} catch (Exception f) {
System.out.println("Can not read file.");
}
}
public void readFile() {
while(opener.hasNext()) {
String a = opener.next();
String b = opener.next();
String c = opener.next();
System.out.printf("%s %s %s\n", a, b, c);
}
}
public void closeFile() {
opener.close();
}
}
and this is the other class:
public class fileTest {
public static void main (String args []) {
Customers c = new Customers();
c.openFile();
c.readFile();
c.closeFile();
}
}
opener might be null as there could be an exception in opening the file
public void openFile() throws Exception{
opener = new Scanner (new File ("customer.txt"));
}
If there is any exception in opening the file, then just a message is printed and opener remains null which will lead to NPE in opener.hasNext()
You should not catch the exception instead throw the exception because if you are not able to open the file, then the code should fail and the other methods should not execute.
Your question is not clear, but you seem to be saying that opener.hasNext() is throwing an NPE.
If so, that means that opener is null. That in turn means that either you are not calling openFile() OR you are calling it but it is not working. I suspect the latter, especially since the main method does call openFile().
If the openFile() method fails to open the file (e.g. because it doesn't exist with the pathname as given), then a message is printed and opener remains null. This is probably what is happening.
The openFile() method has a number of flaws:
it is catching Exception ... which could catch other exceptions than the one(s) you are expecting.
it is not logging the stacktrace or the actual exception message
it is assuming that the problem is due to not being able to open the file ... when it could possibly be something else (in general, if not in this particular case),
once it has printed the error message, it just continues as if nothing bad had happened.
The NPE problems are then a consequence of the openFile() flaws.
Note that if you print out the actual exception message, it should tell you why the application is unable to open the file.
UPDATE
The error message customer.txt (The system cannot find the file specified) is clearly telling you that it can't find the file. The chances are that your application's current directory is not the directory that contains that file. Since you used a relative pathname, you told it it look in the current directory. The solution is to either use an absolute (full) pathname ... or make sure your application is launched with the right current directory.
Once you get past this problem, there is a problem in the way that you are reading the file. The readFile() method is assuming that it is going to be able to read multiples of 3 tokens (strings) from the input. If there is a problem with the file format, you are liable to get an (unchecked) exception. You probably should catch this exception and produce a diagnostic ... rather than assuming that nothing bad can happen.
First:Make sure your file actually exists in the disk, it is possible to create a File object even if the file does not exists.
Second:You are checkin for one element by doin opener.hasNext() and accessing next 3 elements!
When there is only one element in the list opener.hasNext() return true but you are accessing next 2 elements which are not present! hence the null pointer exception
your opener is not getting initialized that why the null pointer exception, make sure the file exists there and just try to give absolute path of the file
Check few points here:
Is your program reading the file specified?If you are using eclipse,keep your file in src folder and give path as opener = new Scanner (new File ("src/customer.txt"));
2.The second problem with your code is you are only checking once for while(opener.hasNext()) for next element and then reading three elements String a = opener.next();
String b = opener.next();
String c = opener.next(); .If there is no next element in your file you will get an exception ,check for each element before accessing it.
use this code instead:
public void readFile() {
while(opener.hasNext()) {
String a = opener.next();
System.out.printf("%s\n", a);
}
}