Acccessing a class from an external jar - java

I have searched for hours and I am not finding a solution, this is my last resort
I have a program that creates a data file via serialization, and the file is created successfully, and I can read the data (Deserialization) using the same program/ package.
The problem I have is that the data file must be read from another program and I have created the same class but I cannot read from the file (Class not found error) from a different program
//Class
public static class
{
File inst_path = ....
}
So I created an external class so that I can create the data file from the same class and read using the same class. The class is saved as a jar file
How can I link both programs to the same class (External File)
Edit
Currently I am accessing my local these way
records.classes myclass = new records.classes()
myclass.inst_path = new File...
So I am looking for something that will look something like ...
externaljar.jar.classes myclass = new ...
I know this won't work but I need something like it.

You just need the jar to be in the classpath of the two programs. Then you use the class as any other class: by importing it and using its name:
java -cp jarWithCommonSerializedClass.jar;jarWithTheProgramClasses.jar the.program.MainClass
Note: this is for Windows. Under *nix, : must be used instead of ;.
See http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html.
Also, respect the Java naming conventions. Java classes start with an upper-case letter. Variables never contain underscores and are camelCased.

Related

How can you load data dynamically with the FMPP Java API?

I am integrating a FMPP transformation into our Java code base. For this, I am using the FMPP Java API. For practical reasons, I have two separate directories:
one which contains the template: <absolute path template>/template.ftlx
one which contains the data: <absolute path data>/data.xml
This somehow complicates things, as I have to work with absolute paths here. Typically, the data is inside the template directory (together with a ignoredir.fmpp file). However, in our application, the data is coming from an external source (it is uploadable via a REST API), while the template is in the classpath. This also means that the data directory isn't static.
I am struggling to define all this and get the transformation happening via the Java API. Currently, I have the following:
Settings s = new Settings(new File("."));
s.set(Settings.NAME_SOURCES, new File("<absolute path template>/template.ftlx").getAbsolutePath());
s.set(Settings.NAME_OUTPUT_FILE, new File("<absolute path output>/output.xml").getAbsolutePath());
s.execute();
The code snippet above is not complete, as I have to add the data. There are the Settings.NAME_DATA and Settings.NAME_DATA_ROOT properties, but I can't get it working. I tried setting Settings.NAME_DATA_ROOT as following:
s.set(Settings.NAME_DATA_ROOT, new File("<absolute path data>").getAbsolutePath());
Then, I get the exception that FreeMarker cannot find my data:
The following has evaluated to null or missing:
==> d [in template "template.ftlx" at line 4, column 12]
In the template, I simply do:
<#list d.items>...</#list>
This makes sense that this would not work, as I did nowhere define that the data should be accessible via the d. hash (which I am doing below in config.fmpp). But I don't know how to define that properly via Settings.NAME_DATA and/or Settings.NAME_DATA_ROOT.
How can I inject my data file into all this? It should get the key d, so I can refer to d. in the template.
reference
Just as reference, if I create the following config.fmpp file in <absolute path config>, put the data.xml data file in directory <absolute path data> and call s.load(new File("<absolute path config>/config.fmpp")) before s.execute() above, everything is working fine.
data: {
d: xml(<absolute path data>/data.xml)
}
All I have to figure out is doing this in a dynamic fashion via the Java API. I cannot use config.fmpp for this, as the location of the data isn't static (and, as far as I know, config.fmpp is not parametrizable).
working solution, with doubts
After some code reading, I got it working if I do the following:
Settings s = new Settings(new File("."));
s.set(Settings.NAME_SOURCES, new File("<absolute path template>/template.ftlx").getAbsolutePath());
s.set(Settings.NAME_OUTPUT_FILE, new File("<absolute path output>/output.xml").getAbsolutePath());
s.set(Settings.NAME_DATA, "{d:xml(<absolute path output>/data.xml)}");
s.execute();
Here, we pass {configuration:xml(<absolute path output>/data.xml)} as a TDD to the NAME_DATA property. Is this the way to go? It "feels" strange to construct a textual definition in our code. Is there a way to do this in pure Java?

Passing a File to another maching with a same JAR file

Here is my problem.
My package setup is:
-src
---- foo
-------- code.java
---- foo.data
-------- files I need to access
Currently I have a jar that contains all of the above files I need to access. I will be running this code on my machine and send File objects initialized on my machine to another machine with the same jar running.
My question is how can I obtain a relative path to the data file so when I send the File objects to the other machine they know to look in the jar?
I need to access the data file so I can perform methods on it. Therefore I need to create a new File(relative/path/to/jar/data/files) with it and then I will be passing the File objects to another computer to compute.
Currently I have been able to use getClass().getResource("data/" + "filename").getPath() this gives me a path like file:/pathtojar!/pathtofileinjar/ which I think will be able to find the jar in the other machine but I am getting null pointer when trying to use the item in the jar. Are files in jar able to be used or is there a workaround for it?
Why not send the relative path of the file in the jar, instead of the File?
The other program can then use that path and read the data from the jar.
Could you try with the absolute path, like so:
package resourcetest;
import java.net.URL;
public class ResourceTest {
public static void main(String[] args) {
new ResourceTest().test();
}
private void test() {
URL res = this.getClass().getResource("/data/data.txt");
System.out.println(res);
}
}
Here my data file that i want to access is data/data.txt
src\resourcetest\ResourceTest.class (this class runs and tries to access data/Data.txt
src\data\Data.txt

java could not find or load main class, using -cp . package.class

I seem to have a problem executing a java class;
I have a static method main(String[] args){};
The class is called Test, in the package ptest
I place the file Test.class in the folder C:\Test\
Then, I navigate to this location in the command prompt.
Finally, in the command line, I run the following: "java -cp . ptest.Test"
This returns:
Error: Could not find or load main class ptest.Test
What am I missing at this point? What else could be causing this error? What I am doing wrong?!
Create a new folder C:\Test\ptest, move Test.class to c:\Test\ptest\Test.class. cd\Test, then java -cp . ptest.Test
The package structure corresponds to the output directory structure.
From Managing Source and Class Files (The Java Tutorials),
Put the source code for a class, interface, enumeration, or annotation type in a text file whose name is the simple name of the type and whose extension is .java. For example:
//in the Rectangle.java file
package graphics;
public class Rectangle {
...
}
Then, put the source file in a directory whose name reflects the name of the package to which the type belongs:
.....\graphics\Rectangle.java
The qualified name of the package member and the path name to the file are parallel, assuming the Microsoft Windows file name separator backslash (for UNIX, use the forward slash).
class name – graphics.Rectangle
pathname to file – graphics\Rectangle.java
Packages map to folders in thee filesystem.
Therefore, ptest.Test maps to ptest/Test.class anywhere in your classpath.

Can I make a Netbeans "empty file" part of compiled jar file?

I have 80,000 words for a crossword (among others) puzzle word pattern matcher. (User inputs "ba??" and gets, among other things, "ball, baby, bank, ..." or enters "ba*" and gets the aforementioned as well as "bat, basket, babboon...".)
I stuck the words in a Netbeans "empty file" and named it "dictionary". The file's contents are just (80,000) words, one per line. This code works like a charm to read the dictionary (code that filters is omitted):
static void showMatches(String pattern, String legal, String w) throws IOException
{
Path p = Paths.get("C:\\Users\\Dov\\Documents\\NetBeansProjects\\Masterwords\\src\\masterwords\\dictionary");
String word;
Scanner sc = new Scanner(p).useDelimiter("\r");
while(sc.hasNext()){
word = sc.next().substring(1);
gui.appendOutput(word);
}
sc.reset();
}
Is there a way to make the file (named "dictionary") become part of the compiled jar file so that I only need to "ship" one file to new, (largely helpless) users?
In another matter of curiosity...
Is it possible to make the argument to Paths.get(...) something like "masterwords/src/dictionary" to make the connection for the Scanner object to be able read it? I'm wondering if this might relate to an answer my first question. (If there's a way, I can't stumble onto it. Whatever similar string I use, I get no error, no output, no "build successful"--gotta click Run > Stop build/run.)
I'm not certain, based on your description, that my solution addresses your issue, but let me restate the problem as I understand it: You have a .jar file that relies on a dictionary resource. That resource is subject to change, and you'd like to be able to update it without having to ship out a whole new .jar containing a new dictionary.
If I'm reading you correctly, you want something like:
private File getInstallPath()
{
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
}
This will return the install directory of your .jar file, which is where you can put your dictionary resource so that the .jar knows where to find it. Of course, now you have a bit of a training issue, because users can move, delete or misplace your dictionary file.
Part II:
Now that you've clarified your question, let me again restate: You want to be able to read an arbitrary file included in your .jar file. Fine. You're probably trying to open the file as a file, but once the file is in your .jar, you need to treat it as a resource.
Try using:
Class myClass = Class.forName("MyClass");
ClassLoader myLoader = myclass.getClassLoader();
InputStream myStream = myLoader.getResourceAsStream(myFile);
Do you really need me to explain what "myClass," "myLoader," etc. refer to? Hint: "myClass" is whatever your class is that needs to read the file.
After leaving this thread in frustration for a couple of weeks, yesterday I found a similar question at this forum, which led me to Google "java resource files" and visit ((this URL)).
Between the two I figured out how to read a file named 'dictionary' that was created as a Netbeans "empty Java file", which was located in Source Packages ... [default package] (as shown in Netbeans Projects window) and stored as C:\Users\Dov\!Docs\Documents\NetBeansProjects\WordPatternHelp\src\dictionary:
File file = new File("src/dictionary");
...
p = file.toPath();
sc = new Scanner(p).useDelimiter("\r");
Success. Hooray.
But after compiling and executing the .jar file from a DOS command line, 'dictionary' couldn't be found. So the above only works from within Netbeans IDE.
After mostly erroneous attempts caused by the above 'success', I finally got success using #Mars' second suggestion like so:
package masterwords;
public class Masterwords
...
InputStream myStream = Class.forName("masterwords.Masterwords").
getClassLoader().getResourceAsStream("dictionary");
sc = new Scanner(myStream).useDelimiter("\r"); // NULL PTR EXCEPTION HERE
So, for whatever it might be worth, a very belated thanks (and another apology) to #Mars. It was as straightforward as he indicated. Wish I'd tried it 2 weeks ago, but I'd never seen any of the methods and didn't want to take the time to learn how they work back then with other more pressing issues at hand. So I had no idea Mars had actually written the exact code I needed (except for the string arguments). Boy, do I know how the methods work now.

Cannot read properties file in Java web app?

I am trying to read a properties file in my java web application. I have tried these solution:
Where to place and how to read configuration resource files in servlet based application?
Howto access properties file from Java EE web application?
But none of them worked for me.
Here is the structure of my app:
The code that reads the properties file is placed in the A class and it did not work even I put the absolute path. A is a normal Java class.
But everything worked like a charm if the reading properties code is place in the servlet class (ProcessRequest.java)
Here is the code I have used:
public class A {
public A() {
try {
Properties p = new Properties();
p.load(this.getClass().getClassLoader().getResourceAsStream("/a.properties"));
String n = p.getProperty("name");
System.out.println("name: " + n);
} catch (Exception ex) {
Logger.getLogger(A.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Any idea?
You've put it in the servlets package, however you're trying it to get from the classpath root. The leading / makes the path relative to the classpath root.
Fix the path accordingly:
p.load(this.getClass().getClassLoader().getResourceAsStream("/servlets/a.properties"));
or, assuming that the current class is in servlets package already:
p.load(this.getClass().getClassLoader().getResourceAsStream("a.properties"));
Unrelated to the concrete problem, might it later happen that you move the properties file outside the WAR to an external location which allows easy editing of the file without the need to rebuild/redeploy everytime, then I'd suggest to use the thread's context class loader instead of the current class' class loader. It'll work in all circumstances:
p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("servlets/a.properties"));
(note that the path doesn't need to start with / here, because it's always relative to classpath root)
Do you see the properties file under WEB-INF/servlets after building the application. If yes then try using following line.
p.load(getServletContext().getResourceAsStream("/WEB-INF/servlets/a.properties"));
instead of this
p.load(this.getClass().getClassLoader().getResourceAsStream("/a.properties"));

Categories

Resources