Accessing File from ClassPath - java

In my Maven project:
src/main/java/App --> has Main
src/main/resources/file.json
.
public class App
{
public static void main( String[] args )
{
URL url = App.class.getClass().getResource("/file.json");
File file = new File(url.getPath());
As I understand these Maven docs, I should be able to access file.json as it (should be) on the classpath since it's located at src/main/resources.
But, I'm getting a NullPointerException on the url.getPath() call.

You are doing App.class.getClass() which is going to get the root classloader (java.lang.Class's classloader), which isn't the same as your application classloader. You want to do App.class.getResource() instead.

Related

Can I store an XML file inside a jar file?

I built an Jar using Maven.
The behavior I am trying to implement is: when the user uses the command create , I want to store an XML file inside a a folder of the jar. Is it possible to do it?
Let's say this is a project and I added the jar of the migration tool to it.
I want to be able to see and edit the properties file
3-It has some things that need to be altered like for example
migration files and the file with the database information
Not 100% sure if I understood your requirements correctly, but I've implemented some utility classes which support:
default config in JAR
config in installation directory
config in user directory
simple command line arguments/ switches support
and more...
Maybe this helps.
public static void main(String[] args) throws URISyntaxException, IOException, MissingPropertyException, Exception {
CommandLineArgs commandLineArgs = CommandLineArgs.parseCommandLineArgs(args);
DromblerClientStarter<DromblerClientConfiguration> main = new DromblerClientStarter<DromblerClientConfiguration>(new DromblerClientConfiguration(commandLineArgs)) {
#Override
protected ApplicationInstanceListener getApplicationInstanceListener() {
return additionalArgs -> {
// additionalArgs not handled
};
}
};
if (main.init()) {
main.start();
}
}
Source code: https://github.com/Drombler/drombler-commons/tree/master/drombler-commons-client/drombler-commons-client-startup-main
Maven:
<dependency>
<groupId>org.drombler.commons</groupId>
<artifactId>drombler-commons-client-startup-main</artifactId>
<version>1.0</version>
</dependency>
Javadoc: https://www.drombler.org/drombler-commons/1.0/docs/site/apidocs/org/drombler/commons/client/startup/main/package-summary.html

Parameter 'directory' is not a directory for a parameter which is a directory

I'm getting a strange error where the parameter I supply to a method complains that it's not a directory but it IS in fact a directory with files in it...I don't understand what's wrong...
Toplevel:
public static File mainSchemaFile = new File("src/test/resources/1040.xsd");
public static File contentDirectory = new File("src/test/resources/input");
public static File outputDirectory = new File("src/test/resources/output");
DecisionTableBuilder builder =constructor.newInstance(log, contentDirectory, outputDirectory);
// Here is where the error occurs
builder.compile(mainSchemaFile);
The class I'm using:
public class DecisionTableBuilder {
public void compiler(File schemaFile) {
...
// It's complaining about contentDirectory, it goes to FileUtils class for this
Collection<File> flowchartFiles = FileUtils.listFiles(contentDirectory, mapExtension, true);
...
}
}
Here is the apache FileUtils class:
public class FileUtils {
private static void validateListFilesParameters(File directory, IOFileFilter fileFilter) {
if (!directory.isDirectory()) {
throw new IllegalArgumentException("Parameter 'directory' is not a directory");
}
if (fileFilter == null) {
throw new NullPointerException("Parameter 'fileFilter' is null");
}
}
}
Output: Parameter 'directory' is not a directory
Which is the error output I am getting...
Anyone have any idea what is happening here I'm super confused...any help will be greatly appreciated.
EDIT:
In my toplevel I added the following line:
if(contentDirectory.isDirectory()) {
System.out.println("Content Directory: "+contentDirectory);
}
Output: src/test/resources/input
You're pointing to the file and not a directory in mainSchemaFile variable. Reduce the path to the folder containing 1040.xsd - it should resolve the issue.
Error is thrown if paths cannot be reached
The file paths that you show do not tell where you try to run the code. If you are in your workspace, but you want to run it on a server, and the paths are meant to be on the server, see as follows:
I saw during debugging in the error logs of the console output of my own project that the code tried to get the data from my workspace. While coding, I thought that it would reach the files on the production server, but it did not.
Exception in thread "my_project" java.lang.IllegalArgumentException: Parameter 'directory' is not a directory
at org.apache.commons.io.FileUtils.validateListFilesParameters(FileUtils.java:545)
at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:521)
at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:691)
With the needed file copied to my workspace and the right path in the code, the error was gone since it found the directory.
In my program, my working directory was the repository from where I ran the code. I had to pull the repository on the server to run it with the working directory on the server, so that it could find the production directory for the input files.

Run program.exe from eclipse plugin project

I am writing an eclipse-plugin witch run program.exe. I have added program.exe to plugin jar file. How can a execute this program?
public class Handler extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
Runtime.getRuntime().exec(/*What should I write here*/);
return null;
}
}
You can't run the program.exe from inside the plugin jar, so it needs to be extracted. In your plugin use:
Bundle bundle = Platform.getBundle("plugin id");
URL url = FileLocator.find(bundle, new Path("relative path to program"), null);
url = FileLocator.toFileURL(url);
This will find the program in the plugin jar and extract it to a temporary location (done by FileLocator.toFileURL).
You should just execute the program like you would in cmd, but now specify the whole path of the programs location.
Runtime.getRuntime().exec("C:\\your\\path\\program.exe");
In the Oracle documentation of the Runtime class you can see the acceptable inputs in exec().

this.getClass().getResource("").getPath() returns an incorrect path

I am currently making a small simple Java program for my Computer Science Final, which needs to get the path of the current running class. The class files are in the C:\2013\game\ folder.
To get this path, I call this code segment in my main class constructor:
public game(){
String testPath = this.getClass().getResource("").getPath();
//Rest of game
}
However, this command instead returns this String: "/" despite the correct output being "C:/2013/game"
Additionally, I attempted to rectify this by using this code:
public game(){
String testPath = this.getClass().getClassLoader().getResource("").getPath();
}
This returns a NullPointerException, which originates from the fact that getClassLoader() returns null, despite working on my Eclipse IDE. Any Ideas?
If you want to load a file in the same path as the code then I suggest you put it in the same root folder as the code and not the same path as the class.
Reason : class can be inside a jar, data file can be put in same jar but its more difficult to edit and update then.
Also suggest you see the preferences class suggested in comments : http://www.javacodegeeks.com/2011/09/use-javautilprefspreferences-instead-of.html though in some cases I think its okay to have your own data/ excel/csv/ java.util.Properties file
Not sure about why it is working in eclipse but I would suggest you focus on running it from a command prompt/ terminal as that is the 'real mode' when it goes live
You could just ask for your class
String s = getClass().getName();
int i = s.lastIndexOf(".");
if(i > -1) s = s.substring(i + 1);
s = s + ".class";
System.out.println("name " +s);
Object testPath = this.getClass().getResource(s);
System.out.println(testPath);
This will give you
name TstPath.class
file:/java/Projects/tests3b/build/classes/s/TstPath.class
Which is my eclipse build path ...
need to parse this to get the path where the class was loaded.
Remember:
App could be started from elsewhere
class can be in jar then path will be different (will point to a jar and file inside that
classpaths can be many at runtime and point 1
a class might be made at runtime via network/ Proxy / injection etc and thus not have a file source, so this is not a generic solution.
think what you want to acheive at a higher level and post that question. meaning why do you want this path?
do you want the app path :-
File f = new File("./");
f.getCanonicalPath();//...
So an app can be started from folder c:\app1\run\
The jar could be at c:\app1\libsMain\myapp.jar
and a helper jar could be at c:\commonlibs\set1
So this will only tell you where the JVM found your class, that may or maynot be what you need.
if inside a jar will give you some thing like this in unix or windows
jar:file:c:\app\my.jar!/s/TstPath.class
If package is s and class is TstPath, you can be sure this will work as the class has to be there ...
now to parse this you can look for your class name and remove / or \ till you get path you want. String lastIndexOf will help
You can use :
URL classURL = getClass().getProtectionDomain().getCodeSource().getLocation();
The call to getResource([String]) requires a path relative to the folder that contains the class it is being called from. So, if you have the following, anything you pass into MyClass.class.getResource([path]); must be a valid path relative to the com/putable/ package folder and it must point to a real file:
package com.putable;
public class MyClass{}
Using the empty string simply isn't valid, because there can never be a file name that equals the empty string. But, you could do getResource(getClass().getSimpleName()). Just remove the file name from the end of the path returned by that call and you will have the class directory you want.
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("Test.class"));
also
Test.class.getProtectionDomain().getCodeSource().getLocation().getPath());
Try this.
import java.io.File;
public class TT {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String path = TT.class.getResource("").getPath();
File file = new File(path);
System.out.println(file.getAbsolutePath());
}
}
Try use this code
public game()
{
String className = this.getClass().getSimpleName();
String testPath = this.getClass().getResource(className+".class");
System.out.println("Current Running Location is :"+testPath);
}
visit the link for more information
Find where java class is loaded from
Print out absolute path for a file in your classpath i.e. build/resources/main/someFileInClassPath.txt Disclaimer, this is similar to another solution on this page that used TT.class..., but this did not work for me instead TT..getClassLoader()... did work for me.
import java.io.File;
public class TT {
/**
* #param args
*/
public static void main(String[] args) {
String path = TT.getClassLoader().getResource("someFileInClassPath.txt").getPath();
File file = new File(path);
System.out.println(file.getAbsolutePath());
}
}
Because you used class.getResource(filePath).getpath() in a *.jar file. So the path includes "!". If you want to get content of file in *.jar file, use the following code:
MyClass.class.getResourceAsStream("/path/fileName")

Trigger Hadoop Command by JAVA code

How to trigger a jar working on Hadoop from a simple jar, so that it uses HDFS, Actully, I am manually running this command bin/hadoop jar ~/wordcount_classes/word.jar org.myorg.WordCount ~/hadoop-0.20.203.0/input1 ~/hadoop-0.20.203/output2 in which I have provided Input and Output directory in HDFS and I am using word.jar here, I want to make it such that it automatically gets triggered from Java Project.
In best of my understanding all you asking for is done by the Main of your jar. It read parameters, creates job configuration, sets input and output formats and finally runs the job.
I'm working on the same problem. I have a program (let's call it Driver) that must implement the following method:
public void runJar(File jar, String mainClass, File inputDir, File outputDir);
To do this, I was calling org.apache.hadoop.util.RunJar.main(String[]) which is what your command-line is calling. This works great only if you're running Driver from the command line.
If Driver is running inside a container (like Tomcat or Jetty), you're going to have a problem. You'll get errors like
java.lang.ClassNotFoundException: org.apache.hadoop.fs.Path
This is because of how RunJar messes with classloaders. You need to manually create a classloader like so:
final ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
URL[] urls = new URL[] { jar.toURI().toURL() };
ClassLoader loader = new URLClassLoader(urls, originalLoader);
Thread.currentThread().setContextClassLoader(loader);
Class<?> mainClass = Class.forName(driverClass, true, loader);
Class[] argTypes = new Class[]{ Array.newInstance(String.class, 0).getClass()};
Method main = mainClass.getMethod("main", argTypes);
main.invoke(null, new Object[] { args });
} finally {
Thread.currentThread().setContextClassLoader(original);
}

Categories

Resources