So, I'm working on a program that allows you to import animations in the form of JSON files into Minecraft, and, when working on a completely different part of the program, my import code stopped working.
I'm using eclipse, and this is how my import code looks:
package com.github.sam54123.mc_animation.utils;
import java.io.InputStream;
public class FileHandle
{
public static InputStream inputStreamFromFile(String path)
{
try
{
InputStream inputStream = FileHandle.class.getResourceAsStream(path);
return inputStream;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
new file
package com.github.sam54123.mc_animation.utils;
import java.io.File;
import java.io.InputStream;
import java.util.Scanner;
import org.json.JSONObject;
public class JSONUtils
{
public static String getJSONStringFromFile(String path)
{
// Open file
Scanner scanner;
try
{
InputStream in = FileHandle.inputStreamFromFile(path);
scanner = new Scanner(in);
// Get JSON as string without spaces or newlines
String json = scanner.useDelimiter("\\Z").next();
// Close file
scanner.close();
return json;
}
catch(Exception e)
{
System.out.println(e.getStackTrace());
return null;
}
}
public static JSONObject getJSONObjectFromFile(String path)
{
File file = new File(path);
if (!file.exists())
{
System.out.println("Invalid Path");
return null;
}
String string = getJSONStringFromFile(path);
return new JSONObject(string);
}
}
And I proceed to do some more fancy pampering of the file later on. This used to work reliably, until I made this in a completely different and un-related class:
String command = getCommand(object);
if (command != null && command.length() > 0)
{
commands.add(new AnimCommand(command, i));
}
And then it started throwing this error:
[Ljava.lang.StackTraceElement;#7852e922
Exception in thread "main" java.lang.NullPointerException
at java.io.StringReader.<init>(Unknown Source)
at org.json.JSONTokener.<init>(JSONTokener.java:94)
at org.json.JSONObject.<init>(JSONObject.java:406)
at com.github.sam54123.mc_animation.utils.JSONUtils.getJSONObjectFromFile(JSONUtils.java:47)
at com.github.sam54123.mc_animation.system.Animation.<init>(Animation.java:20)
at com.github.sam54123.mc_animation.testing.Tester.main(Tester.java:13)
I've double checked that the file hasn't changed, and I tried deleting that section of code, restarting Eclipse, the whole deal, and nothing seems to fix it. The code is even able to recognize that the file is valid using the File class, but nothing seems to change. Does anyone have some insight on how this might be fixed? Here is the rest of my code: https://github.com/Sam54123/mc-animation/
EDIT
Okay, I've just done some more debugging, and it looks like it's the
return new JSONObject(string);
on line 47 of the second file that's crashing. No idea why, as the risky stuff of reading a file off disk is okay.
EDIT 2
It looks looks like it's failing because
InputStream in = FileHandle.inputStreamFromFile(path);
is returning null, which makes sense because of the try catch statement
InputStream inputStream = FileHandle.class.getResourceAsStream(path);
is in. Why that's failing beats me though, because the validity of the file is verified elsewhere in the code. It also used to work, and I haven't changed anything about the layout of the files.
EDIT 3
Interesting, a couple System.out.printlns reveal the catch is not actually getting activated, and therefore getResourceAsStream() must actually be returning null. I've confirmed this by printing it out before I return it.
Related
I want to have a setting system that I can read write and use variables from the are stored in a file.
To summarize, There is a class and inside that class is a list of settings.
When I make a setting I want to add it to the list so that I can write it to the text file later.
I also want to be able to get the setting value without casting it which would use generics.
So for boolSetting I would only need to do boolSetting.get() or boolSetting.value ect
To start with code I have already written I have the code to read and write to the file. This works perfect (I think). I just need help with the setting part. Here is the read and write to file.
package winter.settings;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import net.minecraft.src.Config;
import winter.Client;
public class WinterSettings {
public static File WinterSetting;
public static void readSettings() {
try {
File WinterSetting = new File(System.getProperty("user.dir"), "WinterSettings.txt");
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(new FileInputStream(WinterSetting), "UTF-8"));
String s = "";
while ((s = bufferedreader.readLine()) != null)
{
System.out.println(s);
String[] astring = s.split(":");
Client.modules.forEach(m ->{
if(m.name==astring[0]) {
m.settings.forEach(setting ->{
if(setting.name==astring[1]) {
setting.value=astring[2];
}
});
}
});
}
bufferedreader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeSettings() {
try {
File WinterSetting = new File(System.getProperty("user.dir"), "WinterSettings.txt");
PrintWriter printwriter = new PrintWriter(new FileWriter(WinterSetting));
Client.modules.forEach(m ->{
m.settings.forEach(setting ->{
printwriter.println(m.name+":"+setting.name+":"+setting.value);
});
});
printwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pretty much how this works is I have a setting in a Module which just stores some information.
The setting has a name and a value
To write it I am just writing
The module name, the setting name, the setting value For example: ModuleName:SettingName:false
This works fine, but leads to the problem that I just don't know enough about generics. I can't find a way that works with writing reading and setting / getting. The setting should have a name and value. Some code I wrote is below I just don't know how to continue it.
public class Setting<T> {
public String name;
public T value;
public Setting(String name, T value) {
this.name = name;
this.value = value;
}
public T getValue() {
return value;
}
}
From here I have subclasses for each type of setting. Not sure if this is good programming or not.
Now I can set get / write, but when I read the value isn't updated correctly.
Right now I make a new setting like
private final BooleanSetting toggleSprint = new BooleanSetting("ToggleSprint", true);
There is one problem to this from what I can tell. First off when I try to add it to a list when initilizing I get an error.
Type mismatch: cannot convert from boolean to BooleanSetting.
In short: I need to be able to read write get and set a value in a setting object. This can be boolean / int / ect.
Above is some of my code to read / write to txt file. Setting class and what I have of making a new setting.
My 2 problems are that I read the settings correctly and when making them I can't add them to a list.
Use the Boolean.True static variable
new BooleanSetting("ToggleSprint", Boolean.TRUE);
or
Boolean.valueOf(true)
I am trying to complete a lab where the teacher has asked us to write a test that can read a csv file into a hashmap. He gave us two files one called 'ConfigurationProvider.java' and another called basses.csv to use to write a data driven TestNG case.
ConfigurationProvider.java looks like this
package framework;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
public class ConfigurationProvider {
public HashMap<String, String> getPropertiesFromResourceFile(String fileName) throws Exception {
InputStream inputStream = null;
Properties properties = new Properties();
try {
inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
if(inputStream == null) {
throw new RuntimeException(fileName + " was not found in the Resources folder.");
}
properties.load(inputStream);
}
finally {
inputStream.close();
}
HashMap<String, String> propertyValuesByKey = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
propertyValuesByKey.put(key, value);
}
return propertyValuesByKey;
}
}
and basses.csv looks like this
Make,Model,StringCount
Warwick,Corvette,5
Warwick,Thumb,5
Warwick,Streamer,5
Fender,Precision,4
Fender,Jazz,4
Yamaha,BB500,5
So far I have written the test as follows
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import framework.ConfigurationProvider;
public class BassesProvider {
#Test(dataProvider = "bassProvider")
public void canPrintMap(String make, String model) {
System.out.println(make + ":" + model);
}
#DataProvider(name = "bassProvider")
public Object[][] getData() throws IOException {
String FILE_PATH =
"C:\\Users\\name\\git\\practice\\automation\\src\\test\\resources\\basses.csv";
ConfigurationProvider basses = new ConfigurationProvider();
try {
basses.getPropertiesFromResourceFile(FILE_PATH);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object[][] data = new Object[2][7];
data[0][0] = basses;
return data;
}
}
I am getting the error: java.lang.NullPointerException: Cannot invoke "java.io.InputStream.close()" because "inputStream" is null, etc... and I'm not sure what changes to make or how to proceed further.
I'm not sure what changes to make or how to proceed further.
First you need to work out why the code is throwing an NPE.
Look carefully at the stacktrace.
Work out where the NPE is thrown.
Work out where the null comes from.
Hint 1: carefully read the javadoc for the method that is setting the variable that contains the null.
Now my understanding is that your actual task is to write unit tests. And (without giving the game away) the reasons you are getting an NPE are a combination of a bug in the code you are testing and a flaw in the way that you have (ummm) set up the test environment.
Hint 2: The ConfigurationProvider code that you are testing is NOT designed to load data from a file in the file system. See Hint 1.
This bug is happening only in win10. Currently in win7 it does not happen.
Essentially I write some text that the user has inputted in various fields.
I use this to save all the info the user wrote, so when the application is relaunched the info is already there.
Also, I call this class every time the user clicks a button.
With normal behavior, the application runs fine on win7, and it saves everything properly. With win10 though, saving effectively "corrupts" the file, or at least, it makes it empty.
package whatever;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class SaveFile {
public static void mainSave(String[] args) {
Properties prop = new Properties();
OutputStream output = null;
try {
String instaPathCombined = "config.properties";
output = new FileOutputStream(instaPathCombined);
// set the properties value, the get methods all retrieve a string.
prop.setProperty("a", UI.geta());
prop.setProperty("b", UI.getb());
prop.setProperty("c", UI.getc());
prop.setProperty("d", UI.getd());
prop.setProperty("e", UI.gete());
prop.setProperty("f", UI.getf());
prop.setProperty("g", UI.getg());
prop.setProperty("h", UI.geth());
prop.setProperty("i", UI.geti());
prop.setProperty("j", UI.getj());
prop.setProperty("k", UI.getk());
prop.setProperty("l", UI.getl());
prop.setProperty("m", UI.getm());
prop.setProperty("n", UI.getn());
prop.setProperty("o", UI.geto());
prop.setProperty("p", UI.getp());
prop.setProperty("q", UI.getq());
prop.setProperty("r", UI.getr());
prop.setProperty("s", UI.gets());
prop.setProperty("t", UI.gett());
prop.setProperty("u", UI.getu());
prop.setProperty("v", UI.getv());
// save properties to project root folder
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I have no idea on why it does this.
Also, this is literally a win10 issue, no other factors matter here, as I tried it on a VM with a fresh win10 installation and it happened.
so I'm currently working on reading information from a text file from the first time, and from what I have pieced together, the following code should work and return 100 and 16:
package Utility;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class textReader {
public textReader()
{}
public Object fetchElement(String fileName, String keyName)
{
Properties properties = new Properties();
try {
properties.load(new FileInputStream("P:/Real_Time_Survival/Real_Time_Survivial_Game/assets" + fileName));
} catch (IOException e) {
}
return properties.getProperty("keyName");
}
}
but when called from the main class with
textReader ready = new textReader();
ready.fetchElement("Sprites/ExampleSprite/Default/SpriteData.txt", "FrameDuration");
ready.fetchElement("Sprites/ExampleSprite/Default/SpriteData.txt", "AnimationFrames");
It returns null (have the system printing out those lines, cut it out due to formatting errors). Any idea as to why this won't work?
I'm going to stick my neck out and guess you left off a "/" after "assets"
I um, put the keyName variable as a string.
Yep this is solved, 10/10 best dumb mistakes ever
I use this test to convert txt to pdf :
package convert.pdf;
//getResourceAsStream(String name) : Returns an input stream for reading the specified resource.
//toByteArray : Get the contents of an InputStream as a byte[].
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import convert.pdf.txt.TextConversion;
public class TestConversion {
private static byte[] readFilesInBytes(String file) throws IOException {
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
private static void writeFilesInBytes(byte[] file, String name) throws IOException {
IOUtils.write(file, new FileOutputStream(name));
}
//just change the extensions and test conversions
public static void main(String args[]) throws IOException {
ConversionToPDF algorithm = new TextConversion();
byte[] file = readFilesInBytes("/convert/pdf/text.txt");
byte[] pdf = algorithm.convertDocument(file);
writeFilesInBytes(pdf, "text.pdf");
}
}
Problem:
Exception in thread "main" java.lang.NullPointerException
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:218)
at convert.pdf.TestConversion.readFilesInBytes(TestConversion.java:17)
at convert.pdf.TestConversion.main(TestConversion.java:28)
I use the debugger, and the problem seems to be located here :
private static byte[] readFilesInBytes(String file) throws IOException {
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
What is my problem?
Sounds like the resource probably doesn't exist with that name.
Are you aware that Class.getResourceAsStream() finds a resource relative to that class's package, whereas ClassLoader.getResourceAsStream() doesn't? You can use a leading forward slash in Class.getResourceAsStream() to mimic this, so
Foo.class.getResourceAsStream("/bar.png")
is roughly equivalent to
Foo.class.getClassLoader().getResourceAsStream("bar.png")
Is this actually a file (i.e. a specific file on the normal file system) that you're trying to load? If so, using FileInputStream would be a better bet. Use Class.getResourceAsStream() if it's a resource bundled in a jar file or in the classpath in some other way; use FileInputStream if it's an arbitrary file which could be anywhere in the file system.
EDIT: Another thing to be careful of, which has caused me problems before now - if this has worked on your dev box which happens to be Windows, and is now failing on a production server which happens to be Unix, check the case of the filename. The fact that different file systems handle case-sensitivity differently can be a pain...
Are you checking to see if the file exists before you pass it to readFilesInBytes()? Note that Class.getResourceAsStream() returns null if the file cannot be found. You probably want to do:
private static byte[] readFilesInBytes(String file) throws IOException {
File testFile = new File(file);
if (!testFile.exists()) {
throw new FileNotFoundException("File " + file + " does not exist");
}
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
or better yet:
private static byte[] readFilesInBytes(String file) throws IOException {
InputStream stream = TestConversion.class.getResourceAsStream(file);
if (stream == null) {
throw new FileNotFoundException("readFilesInBytes: File " + file
+ " does not exist");
}
return IOUtils.toByteArray(stream);
}
This class reads a TXT file in the classpath and uses TextConversion to convert to PDF, then save the pdf in the file system.
Here TextConversion code :
package convert.pdf.txt;
//Conversion to PDF from text using iText.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import convert.pdf.ConversionToPDF;
import convert.pdf.ConvertDocumentException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
public class TextConversion implements ConversionToPDF {
public byte[] convertDocument(byte[] documents) throws ConvertDocumentException {
try {
return this.convertInternal(documents);
} catch (DocumentException e) {
throw new ConvertDocumentException(e);
} catch (IOException e) {
throw new ConvertDocumentException(e);
}
}
private byte[] convertInternal(byte[] documents) throws DocumentException, IOException {
Document document = new Document();
ByteArrayOutputStream pdfResultBytes = new ByteArrayOutputStream();
PdfWriter.getInstance(document, pdfResultBytes);
document.open();
BufferedReader reader = new BufferedReader( new InputStreamReader( new ByteArrayInputStream(documents) ) );
String line = "";
while ((line = reader.readLine()) != null) {
if ("".equals(line.trim())) {
line = "\n"; //white line
}
Font fonteDefault = new Font(Font.COURIER, 10);
Paragraph paragraph = new Paragraph(line, fonteDefault);
document.add(paragraph);
}
reader.close();
document.close();
return pdfResultBytes.toByteArray();
}
}
And here the code to ConversionToPDF :
package convert.pdf;
// Interface implemented by the conversion algorithms.
public interface ConversionToPDF {
public byte[] convertDocument(byte[] documentToConvert) throws ConvertDocumentException;
}
I think the problem come from my file system (devbox on windows and server is Unix).
I will try to modify my classpath.
This problem may be caused by calling methods on test.txt, which can be a folder shortcut. In other words, you're calling a method on a file that doesn't exist, resulting in a NullPointerException.