Java loading a resource from outside the classpath (pentaho) - java

I am a couple of weeks into Java programming and are trying to get the pentao report definition from a folder that is outside the class path, but have so far been unsuccessful.
The following successfully loads the definition from a folder contained in the class path, however I am unable to figure out how to get it from an absolute path outside the class path:
// Parse the report file
final URL reportDefinitionURL = classloader.getResource("some/path/inclass/Sample1.prpt");
final ResourceManager resourceManager = new ResourceManager();
final Resource directly = resourceManager.createDirectly(reportDefinitionURL, MasterReport.class);
return (MasterReport) directly.getResource();
I am not sure if this is pentaho-specific or a generic Java issue, but how can I get the file definition based on a absolute path (linux) which is not located in the class path such as
"/usr/share/pentaho/Sample1.prpt" ?
I have tried this:
File file = new File("/usr/share/pentaho/");
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
final URL reportDefinitionURL = cl.getResource("Sample1.prpt");
I have also tried including the external path at runtime but that does not appear to work either:
java -cp ./lib/*:/usr/share/pentaho/*.prpt ...
Any assistance is greatly appreciated !

Default system class loader will look for resources only in the class path. If u know the absolute path, it would be easier to create the URL object directly:
URL reportDefinitionURL = new URL("file:/tmp/Sample1.prpt");
I am not familiar with the pentaho api's, so not sure how the following api works.
resourceMgr.createDirectly(reportDefinitionURL, MasterReport.class);
In last line it is returning an instance of "MasterReport", so "MasterReport.class" should be there in your class path.
EDIT:
I just looked at this pentaho wiki - http://wiki.pentaho.com/display/Reporting/Using+the+DocumentBundle+Reader+and+Writer
Looks like the createDirectly() apis can take a file object
File reportDefinitionFile = new File ("/tmp/Sample1.prpt");
resManager.createDirectly(reportDefinitionFile, MyClass.class);

Related

getResourceAsStream in dynamically loaded jar

I kow there are dozens (if not hundreds) questions about Java's getResource/getResourceAsStream but i did not find any answers to my problem.
I load jars dynamically with: (String path is given)
File jar = new File(path);
URL url = new URL("file", "localhost", jar.getAbsolutePath());
URLClassLoader loader = new URLClassLoader(new URL[] { url });
c = loader.loadClass(name);
Then within the jar i try to load a resource in the jar. This resource clearly exists in the jar and the whole procedure works if I just run the whole thing with a class loader in Eclipse. In a jar it does not work.$
getClass().getResourceAsStream("resource.dat");
I tried every possible combination of /packageName/resource.dat, packageName/resource.dat, /resource.dat and resource.dat. They all throw a stream closed Exception.
The I tried debugging and ended up printing the URL of these files loaded via getClass().getResource(path)
This led to following URL and it does not look normal to me. Is it supposed to say "localhostC:..."?
jar:file://localhostC:\Users\******\export.jar!/packageName/resource.dat
Converting this URL also throws an Exception (URISyntaxException).
Is this URL really broken or am I just doing something wrong?
Try changing the line:
URL url = new URL("file", "localhost", jar.getAbsolutePath());
to
URL url = new URL("file", null, jar.getAbsolutePath());
The host parameter in the URL constructor is not applicable in this case.
First, the File class has a toURI() method, so the preferred way to get a URL pointing to a file is:
URL url = new File(path).toURI().toURL();
So using this, the class loader:
File jar = new File(path);
URLClassLoader loader = new URLClassLoader(new URL[] { jar.toURI().toURL() });
Next, when you want to load a resource for the jar, use a Class that is originating from the jar, so if you already loaded the Class c:
Class<?> c = loader.loadClass(classPathAndName);
URL resource = c.getResource("data.txt");
This will result in something like:
jar:file:/C:/test/testjar.jar!/testpkg/data.txt
Alternatively you can use the ClassLoader to get the resource like:
loader.getResoure(packageAndResourceName);
But note that this quoting from the javadoc:
This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.

how to get inputstream from class file existed in other project

I am trying to get inputstream from class file of the other project.
I am using eclipse. The output folder is:
mycurrentproject/WebContent/WEB-INF/classes.
The export library folder is:
mycurrentproject/WebContent/WEB-INF/lib.
When I print "java.class.path", I got this:
D:\apache-tomcat-7.0.42\bin\bootstrap.jar;D:\apache-tomcat-7.0.42\bin\tomcat-juli.jar;
My environment variable of CLASS PATH of WINDOWS system is:
.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;D:\work\workspace\myjar
My code in package action to get resource stream is:
classfilePath = "/cc/Person.class";
InputStream isInputStream = ModifyMethodTest.class.getResourceAsStream(classfilePath);
Package action is outputed in "mycurrentproject/WebContent/WEB-INF/classes". action.jar is exported in "mycurrentproject/WebContent/WEB-INF/lib".
When cc/Person.class in "mycurrentproject/WebContent/WEB-INF/classes", I got right result. When cc/Person.class in "mycurrentproject/WebContent/WEB-INF/lib" or in "D:\work\workspace\myjar". isInputStream got null. I want to get inputstream form a class file in the other project. The class file maybe in a folder or in a jar file in the target project folder. There should be many classes or jar files in that project. How to do that? For now, and for simple, I test my idea as above to put cc/Person.class in "D:\work\workspace\myjar". But It failed either. Any one have similar experience or advices? Thanks.
EDIT:
classfilePath ="file:D:/work/workspace/myjar/cc/Person.class";
URL[] urls = new URL[] { new URL(classfilePath) };
URLClassLoader ucl = new URLClassLoader(urls);
InputStream isInputStream = ucl.getResourceAsStream(classfilePath);
Here isInputStream still got null. The parameter of getResourceAsStream() is String name. What could be? Something like relative path? Any references?
EDIT2:
It works with code as follow:
String Path1 = "file:D:/";
String Path2 = "work/workspace/myjar/cc/Person.class";
URL[] urls = new URL[] { new URL(Path1) };
URLClassLoader ucl = new URLClassLoader(urls);
InputStream isInputStream = ucl.getResourceAsStream(Path2);
Use an URLClassLoader. Once you've established it, call:
getResourceAsStream("/work/workspace/myjar/cc/Person.class")
For the InputStream.

Load class within Jar file and get it's path

I know there are already a lot similar questions here, but I couldn't get any smarter form them. I want to load a class inside a jar file, at this point this is no problem, but when I want to pass the path to my own ClassLoader it throws an exception it cannot find the class. Is it possible to load a class inside a jar using an absolute path? For instance,Class cls = loader.loadClass(/path/MyPlugin.jar/MyPlugin.class);
But when I do this:
File test = new File("path/plugins/MyPlugin.jar/MyPlugin.class");
System.out.println(test.exists());
It prints out false. I tried using MyPlugin.jar!/MyPlugin.class or MyPlugin.jar.jar!MyPlugin.class which i've seen sometimes on the web, even though i don't really know what it means...
When I do this it finds the class:
URLClassLoader loader = new URLClassLoader(new URL[] { "path/plugins/MyPlugin.jar" });
Class cl = loader.loadClass("MyPlugin");
But now, how can I receive the path? Something like URL url = cl.getResource("MyPlugin"); (which gives back a null)
You can obtain URLs to classpath resources using ClassLoader.getResources. To find a jar with specific class, you may use the following
URL url = classLoader.getResource("com/example/SomeClass.class");
JarURLConnection connection = (JarURLConnection) url.openConnection();
JarFile file = connection.getJarFile();
String jarPath = file.getName();
where classLoader is any classloader capable of finding the class you want to load. If the jar is a part of your application's classpath, you may use system classloader:
ClassLoader classLoader = ClassLoader.getSystemClassloader();
Otherwise, you need to know the jar file location beforehand, and create an instance of URLClassLoader, passing the jar in the constructor:
ClassLoader classLoader = new URLClassLoader(new URL[]{new URL("path/to/the/jar/file.jar")});
and then use it to load your class.
If you want to access a file in your jar file you have to put it in the same directory as the class files are.
For example if Main.class is in bin/my/pkg/Main.class you can store your MyPlugin.class in the same directory (bin/my/pkg/MyPlugin.class) and then, if you want to access that file use
URL url = Main.getResource("MyPlugin.class");
Which uses the location of Main.class in your project as root.
Hope it helps!

Loading a custom class from arbitrary location

I am having some issues with Class Loading in Java. Inside my project I am trying to dynamically load a class from anywhere. However, I am currently failing at loading a hard-coded one and am still clueless after 6 hours of googling and stack-overflow checking.
I am suspecting that there is an issue with the package name of the class I am loading.
My goal is to load the Class LoadAClass.java in the project/resources/dynamicFolderNonInClassPath/loadThis directory. Since I am setting my URLClassLoader to the folder above, its package has been set to
package loadThis;
public class LoadAClass{
static{
System.out.println("I am loaded");
}
(...)
}
However I keep getting a class not found exception.
File file = new File("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath/");
if (!file.exists()) System.out.println("typo!"); //debug print
URL url = file.toURI().toURL();
URLClassLoader loader = new URLClassLoader(new URL[]{url});
String classToBeLoaded = "loadThis.LoadAClass";
Class classy = loader.loadClass(classToBeLoaded);
System.out.println(classy.getCanonicalName()); //debug print
I have tried different combinations, like setting the URLClassLoader to the file directly or giving the full /resources/dynamicFolderNonInClassPath/loadThis as URL but how so far no success.
Someone in christmasy mood and seeing the problem? There seems to be some misunderstanding on my part regarding this functionality and I'd like to see it fixed.
you are missing a forward slash '/'
File file = new File("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath");
if (!file.exists()) System.out.println("typo!"); //debug print
URL url = new URL("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath/");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
String classToBeLoaded = "loadThis.LoadAClass";
Class classy = loader.loadClass(classToBeLoaded);
System.out.println(classy.getCanonicalName()); //debug print
See the third line
A .java file isn't a class file. Have you compiled it? You would need a LoadAClass.class file in a "loadThis" directory with your class loader pointing at the directory that contains "loadThis".

How can I get relative path of the folders in my android project?

How can I get the relative path of the folders in my project using code?
I've created a new folder in my project and I want its relative path so no matter where the app is, the path will be correct.
I'm trying to do it in my class which extends android.app.Activity.
Perhaps something similar to "get file path from asset".
Make use of the classpath.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("path/to/folder");
File file = new File(url.toURI());
// ...
Are you looking for the root folder of the application? Then I would use
String path = getClass().getClassLoader().getResource(".").getPath();
to actually "find out where I am".
File relativeFile = new File(getClass().getResource("/icons/forIcon.png").toURI());
myJFrame.setIconImage(tk.getImage(relativeFile.getAbsolutePath()));
With this I found my project path:
new File("").getAbsolutePath();
this return "c:\Projects\SampleProject"
You can check this sample code to understand how you can access the relative path using the java sample code
import java.io.File;
public class MainClass {
public static void main(String[] args) {
File relative = new File("html/javafaq/index.html");
System.out.println("relative: ");
System.out.println(relative.getName());
System.out.println(relative.getPath());
}
}
Here getPath will display the relative path of the file.
In Android, application-level meta data is accessed through the Context reference, which an activity is a descendant of.
For example, you can get the source directory via the getApplicationInfo().sourceDir property.
There are methods for other folders as well (assets directory, data dir, database dir, etc.).
Generally we want to add images, txt, doc and etc files inside our Java project and specific folder such as /images.
I found in search that in JAVA, we can get path from Root to folder which we specify as,
String myStorageFolder= "/images"; // this is folder name in where I want to store files.
String getImageFolderPath= request.getServletContext().getRealPath(myStorageFolder);
Here, request is object of HttpServletRequest. It will get the whole path from Root to /images folder. You will get output like,
C:\Users\STARK\Workspaces\MyEclipse.metadata.me_tcat7\webapps\JavaProject\images
With System.getProperty("user.dir") you get the "Base of non-absolute paths" look at
Java Library Description

Categories

Resources