java.lang.NullPointerException when using eclipse - java

I am using gephi to implement a function as below, but I don't know where to put the "Personal-May8-Anoymous.gml" file so that eclipse can "see" it.
Container container;
try {
File file = new File(getClass().getResource("Personal-May8-Anoymous.gml").toURI());
container = importController.importFile(file);
container.getLoader().setEdgeDefault(EdgeDefault.DIRECTED); //Force DIRECTED
} catch (Exception ex) {
ex.printStackTrace();
return;
}

By the way it looks, the file should be places in the root of your source folders (another way to view it would be the default package). If you're using maven, put the file in the root of the resources folder.
Here's an example of the project structure:
your_project
- src
+ Personal-May8-Anoymous.gml
- some.package.here
+ YourClass

Remove this line:
File file = new File(getClass().getResource("Personal-May8-Anoymous.gml").toURI());
And modify this:
container = importController.importFile(file);
To:
container = importController.importFile(getClass().getResource("Personal-May8-Anoymous.gml").toURI());

You can see the javadoc (http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource%28java.lang.String%29) to understand the possible places where you can put your file, which is pretty complicated.
But, we can make it simpler, by putting your file in the location that you are familiar with, say C://Users/Personal-May8-Anoymous.gml. To do this, you need to modify:
File file = new File(getClass().getResource("Personal-May8-Anoymous.gml").toURI());
to
File file = new File("C://Users/Personal-May8-Anoymous.gml");
as simple as that.

Related

Proper packaging of runnable Jar project in netbeans

So my task is to create a small program that displays a list of media files and run these media files with default OS media player separately.
My current solution was to create a package that holds all media files, something like:
-com.media
|_a.mp4
|_b.mp4
The following code copies to a temp dir the selected mp4, then runs the default os media player:
public File copyTempMedia(File tempAppFolder, String videoName) {
URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
File from = new File(f.getPath());
File to = new File(tempAppFolder.getAbsolutePath());
try {
FileUtils.copyFileToDirectory(from, to);
} catch (IOException ex) {
Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Temp video copied: " + to.getAbsolutePath() + "/" + to.getName());
return to;
}
public void triggerMediaPlayer(String fileLocation) {
System.out.println("Triggering media player: " + fileLocation);
try {
if (OPERATIN_SYSTEM.contains("Linux")) {
Runtime.getRuntime().exec("sh -c " + fileLocation);
} else if (OPERATIN_SYSTEM.contains("Windows")) {
Runtime.getRuntime().exec("cmd /c " + fileLocation);
}
} catch (IOException ex) {
Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
When I run the program through Netbeans it works as espected, but when I do a clean/build the run the .jar created from the build, the media file doesn't seem to be read, so my questions are:
Why does it work through Netbeans and not through build .jar ?
Is this the best solution to this problem ?
Should I package the media differently ?
Thanks in advance.
Edit
So after running through console instead of double clicking jar, is get a null pointer exception in the line where I read the file:
URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
Why does it work in Netebeans but not on build/jar ?
Is there another place in the jar I could place the media files, so that they are read with no problem through getResource or getResourceAsStream ?
When you run the project in NetBeans, it isn't running the executable jar like java -jar yourproject.jar. Instead it sets the classpath to build/classes sort of like java -cp build/classes com.media.YourMainClass. This means your video files are actual files located in yourproject/build/classes/com/media, and they can be accessed as normal files in the filesystem and copied like a normal file. When you run from the jar, the files are packed in the jar file and can't be copied using simple file copy commands.
Instead of getting the URL by calling getClass().getResource(), try getting an InputStream by calling getClass().getResourceAsStream(). You can then write a simple loop to copy the bytes from the input stream to your temporary file.
This snippet may be helpful:
BufferedInputStream result = (BufferedInputStream) getClass().getResourceAsStream("/com/media/a.mp4");
byte[] bytes = new byte[4098];
try {
result.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(new String(bytes));
You'll need to read the bytes in a loop or something but that should work without needing a separate jar.
I think it's not a good idea to put your media files in the jar because you need to rebuild the project if you want to change one and the jar size will grow.
Use:
File from = new File(String.format("%s/%s", Constants.MEDIA_LOCATION,videoName));
To load your files from the same folder as the jar.
If you want to keep the medias in the jar, create a Maven project and put the mp4 in src/main/resources.
Use maven to create a fat jar and the src/main/resources will be included in the jar.
See 'maven-shade-plugin' to configure the pom.xml and https://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/
Then you can use the others maven's great properties!
See Reading a resource file from within jar
Edit
After some tries, i can't get it right with 'getResource' from the jar.
The path you get from within the jar is like:file:/C:/.../JavaApplication4/dist/JavaApplication4.jar!/test.txt
and not recognized as a valid filesystem path.
You can use 'getResourceAsStream' and copy the file from the jar to the local folder.
InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();
Ok so I found a solution:
Create a separate project with media.*.mp4.
Export as Jar library.
Import library to desktop app.
Make sure library is in classpath.
This solution works for me...
If anyone has a better solution, happy to hear, hopefully before bounty is up :)

Java/Gradle reading external config files

My project structure looks like below. I do not want to include the config file as a resource, but instead read it at runtime so that we can simply change settings without having to recompile and deploy. my problem are two things
reading the file just isn't working despite various ways i have tried (see current implementation below i am trying)
When using gradle, do i needto tell it how to build/or deploy the file and where? I think that may be part of the problem..that the config file is not getting deployed when doing a gradle build or trying to debug in Eclipse.
My project structure:
myproj\
\src
\main
\config
\com\my_app1\
config.dev.properties
config.qa.properties
\java
\com\myapp1\
\model\
\service\
\util\
Config.java
\test
Config.java:
public Config(){
try {
String configPath = "/config.dev.properties"; //TODO: pass env in as parameter
System.out.println(configPath);
final File configFile = new File(configPath);
FileInputStream input = new FileInputStream(configFile);
Properties prop = new Properties()
prop.load(input);
String prop1 = prop.getProperty("PROP1");
System.out.println(prop1);
} catch (IOException ex) {
ex.printStackTrace();
}
}
Ans 1.
reading the file just isn't working despite various ways i have tried
(see current implementation below i am trying)
With the location of your config file you have depicted,
Change
String configPath = "/config.dev.properties";
to
String configPath = "src\main\config\com\my_app1\config.dev.properties";
However read the second answer first.
Ans 2:
When using gradle, do i needto tell it how to build/or deploy the file
and where? I think that may be part of the problem..that the config
file is not getting deployed when doing a gradle build or trying to
debug in Eclipse.
You have two choices:
Rename your config directory to resources. Gradle automatically builds the resources under "src/main/resources" directory.
Let Gradle know the additional directory to be considered as resources.
sourceSets {
main {
resources {
srcDirs = ["src\main\config\com\my_app1"]
includes = ["**/*.properties"]
}
}
}
reading the file just isn't working despite various ways i have tried (see current implementation below i am trying)
You need to clarify this statement. Are you trying to load properties from an existing file? Because the code you posted that load the Properties object is correct. So probably the error is in the file path.
Anyway, I'm just guessing what you are trying to do. You need to clarify your question. Is your application an executable jar like the example below? Are trying to load an external file that is outside the jar (In this case gradle can't help you)?
If you build a simple application like this as an executable jar
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class Main {
public static void main(String[]args) {
File configFile = new File("test.properties");
System.out.println("Reading config from = " + configFile.getAbsolutePath());
FileInputStream fis = null;
Properties properties = new Properties();
try {
fis = new FileInputStream(configFile);
properties.load(fis);
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {}
}
}
System.out.println("user = " + properties.getProperty("user"));
}
}
When you run the jar, the application will try to load properties from a file called test.properties that is located in the application working directory.
So if you have test.properties that looks like this
user=Flood2d
The output will be
Reading config from = C:\test.properties
user = Flood2d
And that's because the jar file and test.properties file is located in C:\ and I'm running it from there.
Some java applications load configuration from locations like %appdata% on Windows or /Library/Application on MacOS. This solution is used when an application has a configuration that can change (it can be changed by manually editing the file or by the application itself) so there's no need to recompile the application with the new configs.
Let me know if I have misunderstood something, so we can figure out what you are trying to ask us.
Your question is slightly vague but I get the feeling that you want the config files(s) to live "outside" of the jars.
I suggest you take a look at the application plugin. This will create a zip of your application and will also generate a start script to start it. I think you'll need to:
Customise the distZip task to add an extra folder for the config files
Customise the startScripts task to add the extra folder to the classpath of the start script
The solution for me to be able to read an external (non-resource) file was to create my config folder at the root of the application.
myproj/
/configs
Doing this allowed me to read the configs by using 'config/config.dev.properies'
I am not familiar with gradle,so I can only give some advices about your question 1.I think you can give a full path of you property file as a parameter of FileInputStream,then load it using prop.load.
FileInputStream input = new FileInputStream("src/main/.../config.dev.properties");
Properties prop = new Properties()
prop.load(input);
// ....your code

Java create a folder in current package folder

In my java program, I want to write files to a folder inside my current package. If this folder doesn't exist, I will create it.
How do I refer to this maybe non-existent folder with relative path, so that if I move my package around, I don't have to manually fix the path?
private void writeFamilyPerFile(String name, ArrayList<String> planNames) {
File file;
File folder = new File(OUTPUT_DIR + "/temp/");
BufferedWriter bw = null;
try {
if(!folder.exists()) {
folder.mkdir();
}
file = new File(folder + name + ".md");
file.createNewFile();
bw = new BufferedWriter(planNames);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException ignore) {
}
}
}
}
OUTPUT_DIR is the path to my current package, and folder is the folder I want to create inside current package directory.
UPDATE
Thanks everyone for answering my question. I'm not very experienced, so is making a lot mistakes.
I'm generating a bunch of markdown files, which could be used as is, and will be processed further later in my app, i.e., merged into 1 single file, and translated into HTML. My app lives inside a project, the file structure is like this:
root
|--other parts
|--definitions
| |--definition
| |--java
| | |--validator
| | |--docGenerator
| |--pom.xml
|--pom.xml
docGenerator is my project. Where should I put:
intermediate generated files, which I'd like to keep
temp files I will generated, use and delete
final output files
resource files my program read and use
Big thanks to everyone!
Well assuming your current path is within the application folder (where your package folders are), and your class files are not within a jar, you can do this.
String OUTPUT_DIR = this.getClass().getCanonicalName().replace(".","/");
OUTPUT_DIR = OUTPUT_DIR.substring(0,OUTPUT_DIR.lastindexOf('/'));
It is very unclear from your Question what you are trying to do. However, I think that this is what you are asking for:
...
File outputDir = new File(OUTPUT_DIR);
File outputFile = new File(outputDir, planNames.get(i) + ".md");
bw = new BufferedWriter(new FileWriter(outputFile));
...
The above opens a file (named planNames.get(i) + ".md") in the directory OUTPUT_DIR. The file is opened for writing as a text file. It will be created if it doesn't exist already, and truncated if it does exist.
This assumes that the output directory already exists, and that OUTPUT_DIR is a String whose value is a resolvable pathname for the directory.
I should also point out that writing files into the project source tree in your IDE is not going to work if your application even needs to run outside of an IDE. (And this is a strange thing to do inside an IDE too ... unless you are generating Java source code.)
In that sense, you are probably asking for the wrong thing; i.e. something that doesn't make sense. If you told us what you are actually trying to do here, we could suggest alternatives that made more sense.

Java Jar file: use resource errors: URI is not hierarchical

I have deployed my app to jar file. When I need to copy data from one file of resource to outside of jar file, I do this code:
URL resourceUrl = getClass().getResource("/resource/data.sav");
File src = new File(resourceUrl.toURI()); //ERROR HERE
File dst = new File(CurrentPath()+"data.sav"); //CurrentPath: path of jar file don't include jar file name
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst);
// some excute code here
The error I have met is: URI is not hierarchical. this error I don't meet when run in IDE.
If I change above code as some help on other post on StackOverFlow:
InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav");
File dst = new File(CurrentPath() + "data.sav");
FileOutputStream out = new FileOutputStream(dst);
//....
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION
//....
}
You cannot do this
File src = new File(resourceUrl.toURI()); //ERROR HERE
it is not a file!
When you run from the ide you don't have any error, because you don't run a jar file. In the IDE classes and resources are extracted on the file system.
But you can open an InputStream in this way:
InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav");
Remove "/resource". Generally the IDEs separates on file system classes and resources. But when the jar is created they are put all together. So the folder level "/resource" is used only for classes and resources separation.
When you get a resource from classloader you have to specify the path that the resource has inside the jar, that is the real package hierarchy.
If for some reason you really need to create a java.io.File object to point to a resource inside of a Jar file, the answer is here: https://stackoverflow.com/a/27149287/155167
File f = new File(getClass().getResource("/MyResource").toExternalForm());
Here is a solution for Eclipse RCP / Plugin developers:
Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
URL resolvedFileURL = FileLocator.toFileURL(fileURL);
// We need to use the 3-arg constructor of URI in order to properly escape file system chars
URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
It's very important to use FileLocator.toFileURL(fileURL) rather than resolve(fileURL)
, cause when the plugin is packed into a jar this will cause Eclipse to create an unpacked version in a temporary location so that the object can be accessed using File. For instance, I guess Lars Vogel has an error in his article - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/
I got a similiar issues before, and I used the code:
new File(new URI(url.toString().replace(" ","%20")).getSchemeSpecificPart());
instead of the code :
new File(new URI(url.toURI())
to solve the problem
While I stumbled upon this problem myself I'd like to add another option (to the otherwise perfect explanation from #dash1e):
Export the plugin as a folder (not a jar) by adding:
Eclipse-BundleShape: dir
to your MANIFEST.MF.
At least when you export your RCP app with the export wizard (based on a *.product) file this gets respected and will produce a folder.
In addition to the general answers, you can get "URI is not hierarchical" from Unitils library attempting to load a dataset off a .jar file. It may happen when you keep datasets in one maven submodule, but actual tests in another.
There is even a bug UNI-197 filed.

where to place sound files relative to a java project?

This is the first time I've implemented sounds but I can't figure out where to actually place the sounds to play them. I am using Eclipse as my IDE and I've put my sounds in a folder called sounds.
The following code is what I've used to create one of the audioclip objects:
private final String background = "." + slash + "sounds" + slash + "background.wav";
main(....){
try {
backgroundClip = Applet.newAudioClip(new File(background).toURI().toURL());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I don't hear anything. When I remove the try/catch I get an error saying that it is unable to find the file. I placed my sound folder in both /src and /bin but neither can find it. where do I put it?
The base for your project is the level above the src folder. So using . will put you at your project folder.
Basically,
. = project_root
./src = default_package
./src/packagename = inside the package named "packagename"
./sounds/background.wav = a .wav file in the sounds folder, in the project_root
Using your current path, you need to put your .wav file in the sounds folder in the project_root.
The path will end up being project_root/sounds/background.wav.
See this thread to understand why application resources should be obtained by URL obtained from getResource(), rather than a File converted to an URL.

Categories

Resources