How can I load a file relative to a class's package? - java

I have the file allDepartments.json in a subdirectory called fixtures, to which I want to access from the Fixture.java class.
This is my Fixture.java code:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public final class Fixture {
private static final String FIXTURES_PATH = "";
private final String fixture;
public Fixture(String fixtureName) throws IOException {
fixture = new String(Files.readAllBytes(Paths.get(FIXTURES_PATH + fixtureName)));
}
public final String getFixture() {
return fixture;
}
}
However every time he tries to access the file I get a java.nio.file.NoSuchFileException: allDepartments.json...
I have heard of the getResource() method and tried every combination possible of it, without success.
I need this to store multi-line strings for my JUnit tests.
What can I do?

The NIO.2 API can't be used to read files that are effectively project resources, i.e. files present on the classpath.
In your situation, you have a Maven project and a resource that you want to read during the unit test of the application. First, this implies that this resources should be placed under src/test/resources so that Maven adds it automatically to the classpath during the tests. Second, this implies that you can't use the Files utility to read it.
You will need to resort to using a traditional BufferedReader:
public Fixture(String fixtureName) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(Fixture.class.getResourceAsStream(FIXTURES_PATH + fixtureName)))) {
// do your thing with br.readLine();
}
}
Note the path given to getResourceAsStream is either relative to the current class or absolute. If the resources is located in src/test/resources/folder/allDepartments.json then a valid path would be /folder/allDepartments.json.

Add allDepartments.json to the.classpath file of the project and java should be able to pick it up.
Refer this topic if you want to know how to add a file to class path from eclipse

when you run Fixtures.java the relative path would be
../fixtures/allDepartments.json
try using this path.

Thank you all for helping and suggestions.
Thanks to you I was able to put things working, so here is the trick (which I guess only works for Maven projects):
I moved the allDepartments.json file to the default src/test/resources folder as suggested by you guys. I didn't even had to modify the pom.xml. And now everything works!
So this is my project structure now:
And the final Fixture.java code is:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public final class Fixture {
private final String fixture;
public Fixture(String fixtureName) throws IOException {
fixture = this.readFile(fixtureName);
}
private String readFile(String fileName) throws IOException {
final InputStream in = this.getClass().getClassLoader().getResource("fixtures/" + fileName).openStream();
final BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
try {
return buffer.lines().collect(Collectors.joining("\n"));
} finally {
buffer.close();
}
}
public final String getFixture() {
return fixture;
}
}

Related

create .gitignore with java

I'm aware this question might be a duplicate in some sense but first hear me out.
I tried to create a code where i can create gitignore file with contents and for some reason i always end up having a file with txt extension and without name. Can someone explain this behavior and why?
Example Code:
System.out.println(fileDir+"\\"+".gitignore");
FileOutputStream outputStream = new FileOutputStream(fileDir+"\\"+".gitignore",false);
byte[] strToBytes = fileContent.getBytes();
outputStream.write(strToBytes);
outputStream.close();
You can use java.nio for it. See the following example:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class StackoverflowMain {
public static void main(String[] args) {
// create the values for a folder and the file name as Strings
String folder = "Y:\\our\\destination\\folder"; // <-- CHANGE THIS ONE TO YOUR FOLDER
String gitignore = ".gitignore";
// create Paths from the Strings, the gitignorePath is the full path for the file
Path folderPath = Paths.get(folder);
Path gitignorPath = folderPath.resolve(gitignore);
// create some content to be written to .gitignore
List<String> lines = new ArrayList<>();
lines.add("# folders to be ignored");
lines.add("**/logs");
lines.add("**/classpath");
try {
// write the file along with its content
Files.write(gitignorPath, lines);
} catch (IOException e) {
e.printStackTrace();
}
}
}
It creates the file on my Windows 10 machine without any problems. You need Java 7 or higher for it.

Java, seemingly randomly, started crashing on FileHandle.class.getResourceAsStream(path);

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.

Does the NullPointerException really depend on the location of the class?

I have two classes in a Maven project, which contain the same code (except for their name). The code shall later create a new class with Javassist based on a csv-file.
The first one CsvParser is placed in the src/main/java/csvParser package. The second one TestCsvParser is placed in the src/test/java/csvParser package. In both packages the same file assistant.csv is placed.
When I run the one from the main directory (CsvParser) I get a java.lang.NullPointerException but when I run TestCsvParser, placed in the testdirectory the same code works fine.
Why is it like that? (Or do I just not see something? ;) )
CsvParser:
package csvParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CsvParser {
public static void main(String[] args) throws IOException
{
createClass("/assistant.csv");
}
/**
* Create a class from a csv-file.
*/
private static void createClass(String input) throws IOException {
try(BufferedReader stream = new BufferedReader(new InputStreamReader(
CsvParser.class.getResourceAsStream(input))))
{
// Create class based on csv-file.
}
}
}
TestCsvParser:
package csvParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestCsvParser {
public static void main(String[] args) throws IOException
{
createClass("/assistant.csv");
}
/**
* Create a class from a csv-file.
*/
private static void createClass(String input) throws IOException {
try(BufferedReader stream = new BufferedReader(new InputStreamReader(
TestCsvParser.class.getResourceAsStream(input))))
{
// Create class based on csv-file.
}
}
}
The exception
Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at csvParser.CsvParser.createClass(CsvParser.java:19)
at csvParser.CsvParser.main(CsvParser.java:11)
I believe this question is not a duplicate of a question like What is a NullPointerException because:
The NullPointerException occurs based on the location of the class and the resource referred to. So it's more about directory structures and Mavens targetdirectory.
Thanks for your time!
Finally I found the error. I added the assistant.csv beside the two classes (CsvParser and TestCsvParser). But in both cases this file is not added to the target directory.
The reason why it was working in TestCsvParser is an additional assistant.csv in the ../test/resource/ directory. In fact the two conditions which I described missed this fact and therefore you could not reconstruct my error fully. I'm sorry for that.
To have a working example the resource files both for main and test have to placed within the resource folder instead of beside the class.
Thanks for your help, especially Kalaiselvan A.
It will depend on location of "/assistant.csv" file and if it's not found, you will get NPE. The path will be dependent on your class location since you are calling CsvParser.class.getResourceAsStream..

getClassLoader().getResourceAsStream method returns null for a file with ".LIB" extension

I'm trying to load a file from resources/ path using
getClassLoader().getResourceAsStream("file.LIB")
but the method always returns null, unless I rename the file into another extension, say ".dll".
I've looked into the official Java documentation, but to no avail.
Why does the method acts strange on that file type?
Note: I'm using JDK 1.8.0_111 x86 (due to constraints on that lib file, which only works well with a 32-bit JVM)
It does works for me, you need to be sure what exactly you are doing with lib file.
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class FileHelper {
public String getFilePathToSave() {
Properties prop = new Properties();
String filePath = "";
try {
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("abc.lib");
prop.load(inputStream);
filePath = prop.getProperty("json.filepath");
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
public static void main(String args[]) {
FileHelper fh = new FileHelper();
System.out.println(fh.getFilePathToSave());
}
}

Distributing a Java program with content

For the past couple of months I've been working on a game in java for a university project. It's coming up to the end of the project and I would like to compile the project into a single file which is easy to distribute. The game currently runs from inside the IDE and relies on the working directory being set somewhere specific (i.e. the content directory with sounds/textures etc). What's the best way to put all this together for portability? I'm hoping there is some way to compile the content into the jar file...
NB. I'm using NetBeans, so any solutions which are easy in netbeans get extra credit ;)
Addendum::
For future reference, I found a way of accessing things by directory, ythis may not be the best way but it works:
File directory = new File(ClassLoader.getSystemResource("fullprototypeone/Content/Levels/").toURI());
And now I can just use that file object as normal
You can embed resources in jar file - this is just a zip after all. The standard way to do that is to put resource files in some directory in your sources hierachy. Then you refer to them by Object.getClass().getResourceAsStream(). So you will need to change the way you retrieve them in your code.
You can read more here: Object.getClass().getResourceAsStream(). Of course instead of object you use some class from your package.
when you put those resource files in your src hierachy I believe Netbeans should jar them for you with standard build of the project.
Here is the manual for JNLP and Java Web Start. These technologies exist just for the task you've described.
Well one way is to access the resources via Class.getResourceAsStream (or Class.getResource). Then make sure that the files are in the JAR file.
Off the top of my head (and without trying it) you should be able to put the resources in with the source files which will get NetBeans to put them into the JAR file. Then change the File stuff to the getResource calls.
I would suggest making a simple program that plays a sound and trying it out before you try to convert the whole project over.
If you try and it doesn't work let me know and I'll see if I can dig into it a bit more (posting the code of the simple project would be good if it comes to that).
Here is the code I promised in another comment... it isn't quite what I remember but it might get you started.
Essentially you call: String fileName = FileUtils.getFileName(Main.class, "foo.txt");
and it goes and finds that file on disk or in a JAR file. If it is in the JAR file it extracts it to a temp directory. You can then use "new File(fileName)" to open the file which, no matter where it was before, will be on the disk.
What I would do is take a look at the getFile method and look at what you can do with the JAR file to iterate over the contents of it and find the files in a given directory.
Like I said, not exactly what you want, but does do a lot of the initial work for you.
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
public class FileUtils
{
public static String getFileName(final Class<?> owner,
final String name)
throws URISyntaxException,
ZipException,
IOException
{
String fileName;
final URI uri;
try
{
final String external;
final String decoded;
final int pos;
uri = getResourceAsURI(owner.getPackage().getName().replaceAll("\\.", "/") + "/" + name, owner);
external = uri.toURL().toExternalForm();
decoded = external; // URLDecoder.decode(external, "UTF-8");
pos = decoded.indexOf(":/");
fileName = decoded.substring(pos + 1);
}
catch(final FileNotFoundException ex)
{
fileName = null;
}
if(fileName == null || !(new File(fileName).exists()))
{
fileName = getFileNameX(owner, name);
}
return (fileName);
}
private static String getFileNameX(final Class<?> clazz, final String name)
throws UnsupportedEncodingException
{
final URL url;
final String fileName;
url = clazz.getResource(name);
if(url == null)
{
fileName = name;
}
else
{
final String decoded;
final int pos;
decoded = URLDecoder.decode(url.toExternalForm(), "UTF-8");
pos = decoded.indexOf(":/");
fileName = decoded.substring(pos + 1);
}
return (fileName);
}
private static URI getResourceAsURI(final String resourceName,
final Class<?> clazz)
throws URISyntaxException,
ZipException,
IOException
{
final URI uri;
final URI resourceURI;
uri = getJarURI(clazz);
resourceURI = getFile(uri, resourceName);
return (resourceURI);
}
private static URI getJarURI(final Class<?> clazz)
throws URISyntaxException
{
final ProtectionDomain domain;
final CodeSource source;
final URL url;
final URI uri;
domain = clazz.getProtectionDomain();
source = domain.getCodeSource();
url = source.getLocation();
uri = url.toURI();
return (uri);
}
private static URI getFile(final URI where,
final String fileName)
throws ZipException,
IOException
{
final File location;
final URI fileURI;
location = new File(where);
// not in a JAR, just return the path on disk
if(location.isDirectory())
{
fileURI = URI.create(where.toString() + fileName);
}
else
{
final ZipFile zipFile;
zipFile = new ZipFile(location);
try
{
fileURI = extract(zipFile, fileName);
}
finally
{
zipFile.close();
}
}
return (fileURI);
}
private static URI extract(final ZipFile zipFile,
final String fileName)
throws IOException
{
final File tempFile;
final ZipEntry entry;
final InputStream zipStream;
OutputStream fileStream;
tempFile = File.createTempFile(fileName.replace("/", ""), Long.toString(System.currentTimeMillis()));
tempFile.deleteOnExit();
entry = zipFile.getEntry(fileName);
if(entry == null)
{
throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
}
zipStream = zipFile.getInputStream(entry);
fileStream = null;
try
{
final byte[] buf;
int i;
fileStream = new FileOutputStream(tempFile);
buf = new byte[1024];
i = 0;
while((i = zipStream.read(buf)) != -1)
{
fileStream.write(buf, 0, i);
}
}
finally
{
close(zipStream);
close(fileStream);
}
return (tempFile.toURI());
}
private static void close(final Closeable stream)
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
}
Edit:
Sorry, I don't have time to work on this right now (if I get some I'll do it and post the code here). This is what I would do though:
Look at the ZipFile class and use the entries() method to find all of the files/directories in the zip file.
the ZipEntry has an isDirectory() method that you can use to figure out what it is.
I think the code I posted in this answer will give you a way to pick a temporary directory to extract the contents to.
I think the code I posted in this answer could help with copying the ZipEntry contents to the file system.
once the items are on the file system the code you already have for iterating over the directory would still work. You would add a new method to the FileUtils class in the code above and be able to find all of the files as you are doing now.
There is probably a better way to do it, but off the top of my head I think that will work.
yes ! put your compiled .class files and your resources with folders in a jar file .. you ll have to build a manifest file as well .. you can find the tutorial about making a .jar file on
google. most probably you ll be referred to java.sun.com .

Categories

Resources