I'm trying to read signals from a PLC trough Java, and for that I think I should use a "bridge" called JEasyOPC. The problem is that I don't how to install it, and make it work.
I followed a tutorial but I get always stuck at the same problem. I get an error:
Property file javafish.clients.opc.JCustomOpc doesn't exist. System terminated.
If you are using JEasyOpc inside a web application (e.g. inside a .war file), then you may need to do the following
Replace this line in PropertyLoader.java with
ClassLoader cl = ClassLoader.getSystemClassLoader();
with
ClassLoader cl = PropertyLoader.class.getClassLoader();
Also, make sure you specify -Djava.library.path=[path to folder containing dll]
The property file is in a directory called resources. If you have the jeasyopc.jar in a directory, /jeasy, then the resources directory should be in a directory such as /jeasy/resources. You need to put this on your classpath. This can be done in your environment or at run time with something like java -Djava.ext.dirs=.:/jeasy/resources .
Related
I'm developing a simple mail sender as Java EE application.
The project structure is shown as follows:
To properly setup email contents, I need to read the *.vm files placed inside the resource folder, that I supposed to have as path classpath:/templates/mail/*.vm (as with Spring)... But my supposition is wrong!
Which is the right path to use?
Should I have to use the META-INF folder? Is this solution more
java-ee-compliant? In that case, where have I to put the META-INF folder inside my project structure?
Update:
I packaged the project as .war, then I putted the files in:
/src/main/webapp/WEB-INF/classes/templates/mail/
Then:
org.apache.velocity.Template t = myVelocityEngine.getTemplate("classpath:/templates/mail/account_to_confirm.vm",
"UTF-8");
Nonetheless, the app returns an error at runtime:
Unable to find resource 'classpath:/templates/mail/account_to_confirm.vm'
What am I doing wrong?
Just to better understand:
Supposing that I'd like to deploy this app as jar (removing the servlet class, of course): in that case, should I have to edit the folder layout in order to still use the same path into the source code?
I think the problem is due to the prefix classpath:: where did you find that you have to use it?
You might find useful understanding how to initialize VelocityEngine reading Loading velocity template inside a jar file and how Configuring Resource Loaders in Velocity.
If you can, use Classloader.getResourceAsStream("templates/mail/*.vm"); or similar getResourceAsURL method.
If not, take a look at where files from resources are placed inside WAR. In your case, the file should be in /WEB-INF/classes/templates/mail .
I am using CLIPSJNI.
What I have is:
Environment clips = new Environment();
clips.load("main.clp");
where main.clp is put in the same level as src and bin folder.
This runs fine in Eclipse. However when I export to JAR. It cannot work.
I understand that there are some problems with the path when we export to JAR.
So I've seen people suggesting using this.getClass().getResourceStream() but this is not the case. Because what I need is the name of the file, not its content.
Any suggestions on how to fix this?
The issue is that the load is being done within the native library on the C side which is being passed a file name as an argument. The C code has no concept of a JAR file or how to extract files embedded within one. I think what you would need to do is always place your .clp files within the JAR file and then have a routine which extracts the data from the JAR file and saves it to a file. You can then load it using the load method and delete the file once done.
This is the well known problem of loading resources from a jar file. This is not the first time I've tried to do this, but now it doesn't work the way I expect it to.
Normally I try to load the Resources with this.getClass.getResource("foo.png"), or getResourceAsStream()and it works. Now however it does not. The Resource is always null.
If I let System.out.println(this.getClass.getResource("")) print me the path (from eclipse) it shows /path/to/eclipseproject/package/structure/. Running this from a jar it just shows rsrc:package/structure
If I recall correctly this should print the path to the jar. Furthermore I thought this would print the package structure in both cases. Am I doing something wrong?
Here is the thing...
When Extracting the file from the Jar use:
this.getClass.getResource("/foo.png")
When running from a runnable Jar use, to reference an external file in the Jar folder path:
this.getClass.getResource("foo.png")
// When running this from Eclipse, it would refer to files in project root!
I have a code in the lower level determining where I'm running from to determine the correct path.
Doe this get the path you need?
this.getClass().getClassLoader().getResource("<your class name>.class").getPath();
See also this question for more on this issue.
Unless you prepend the path to the resources with '/', Class.getResource() will search for the resource in class package. E.g.: tld.domain.Foo.class.getResource("Bar.txt") will search for tld/domain/Bar.txt
Check the URLClassLoader for all the gory details, but it really depends on whether you are trying to access a ressource in the jar,
using a class loaded inside the same jar, in this case your file 'root' is the root of the jar
using a class loaded outside the jar (your eclipse case) where the root is your 'working directory'
To access resources inside a jar from outside, you should use something like
URL url = new URL( "jar", "", "file:" + jar.getCanonicalPath( ) + "!/" + localPathResource );
url.openStream(...)
This answer provides an explanation of how to load class resources from JAR files, even when the class is not in the JAR file and not in the Class-Path specified in the JAR file's manifest. There are also links to code.
I'm newbie to java.
I have some directory structure
product/
conf/
classes/com/../..
conf/ contains some configuration file, while under classes/ I have my application.
How can I ensure from inside java code that I'm able to find file in conf/ despite way I'm executing it (e.g. from eclipse, from different directories, from crontab etc.).
P.S.
Files in conf/ are not resources, since required to be edited by user.
Is there're way to know where my .class, so I canuse relative path form that directory to reach my directory (e.g. MY_CLASS_DIR/../../../../conf)
I would put the conf directory into the class path. That way you can always find them by:
YourClass.class.getClassLoader().getResource("conf/....");
You can use the absolute path, including the way to product.
Or you may use a configuration setting, by starting your program like
java -DXY_HOME=/some/path/product ...
From the javacode, you use it:
String xyHome = System.getProperty ("XY_HOME")
Or you use a kind of inifile in your home directory, where you specify where to look for the conf-directory.
Rereading your question multiple times, it is unclear to me what your goal is. To find the conf dir independently from where you are (eclipse, crontab, ...)? But the headline asks for the CWD, which is the opposite - the directory, depending on where you are.
Both is possible, but you have to decide what you want.
Its safe to use relative paths than absolute paths. Even if you JAR your classes tomorrow it will work as is,
Put you configuration files in classpath during deployment.(Please note that
project directory structure can be different from that of deployment directory structure)
product/
classes/com/../..
classes/conf/some_conf.properties
Then you can use Apache common configuration to get the URL of file
URL urlOfFile = org.apache.commons.configuration.
ConfigurationUtils.locate("conf/some_conf.properties");
The other alternative you can try is,
URL urlOfFile = <SomeClassFromClassesFolder>.class.
getClassLoader().getResource(resourceFile);
Once you get the URL of your configuration file getting stream out of it very simple,
InputStream stream = urlOfFile.openStream();
Good luck.
For you understanding you can refer the following as well,
http://bethecoder.com/applications/tutorials/showTutorials.action?tutorialId=Java_IO_CurrentWorkingDirectory
http://bethecoder.com/applications/tutorials/showTutorials.action?tutorialId=Java_Reflection_WheretheClassloadedfrom
Good luck.
you can find out what is the absolute path of the working dir by:
String str = new File("").getAbsolutePath()
Lots of confusion in this topic. Several Questions have been asked. Things still seem unclear.
ClassLoader, Absolute File Paths etc etc
Suppose I have a project directory structure as,
MyProject--
--dist
--lib
--src
--test
I have a resource say "txtfile.txt" in "lib/txt" directory. I want to access it in a system independent way. I need the absolute path of the project.
So I can code the path as abspath+"/lib/Dictionary/txtfile.txt"
Suppose I do this
java.io.File file = new java.io.File(""); //Dummy file
String abspath=file.getAbsolutePath();
I get the current working directory which is not necessarily project root.
Suppose I execute the final 'prj.jar' from the 'dist' folder which also contains "lib/txt/txtfile.txt" directory structure and resource,It should work here too. I should absolute path of dist folder.
Hope the problem is clear.
You should really be using getResource() or getResourceAsStream() using your class loader for this sort of thing. In particular, these methods use your ClassLoader to determine the search context for resources within your project.
Specify something like getClass().getResource("lib/txtfile.txt") in order to pick up the text file.
To clarify: instead of thinking about how to get the path of the resource you ought to be thinking about getting the resource -- in this case a file in a directory somewhere (possibly inside your JAR). It's not necessary to know some absolute path in this case, only some URL to get at the file, and the ClassLoader will return this URL for you. If you want to open a stream to the file you can do this directly without messing around with a URL using getResourceAsStream.
The resources you're trying to access through the ClassLoader need to be on the Class-Path (configured in the Manifest of your JAR file). This is critical! The ClassLoader uses the Class-Path to find the resources, so if you don't provide enough context in the Class-Path it won't be able to find anything. If you add . the ClassLoader should resolve anything inside or outside of the JAR depending on how you refer to the resource, though you can certainly be more specific.
Referring to the resource prefixed with a . will cause the ClassLoader to also look for files outside of the JAR, while not prefixing the resource path with a period will direct the ClassLoader to look only inside the JAR file.
That means if you have some file inside the JAR in a directory lib with name foo.txt and you want to get the resource then you'd run getResource("lib/foo.txt");
If the same resource were outside the JAR you'd run getResource("./lib/foo.txt");
First, make sure the lib directory is in your classpath. You can do this by adding the command line parameter in your startup script:
$JAVA_HOME/bin/java -classpath .:lib com.example.MyMainClass
save this as MyProject/start.sh or any os dependent script.
Then you can access the textfile.txt (as rightly mentioned by Mark) as:
// if you want this as a File
URL res = getClass().getClassLoader().getResource("text/textfile.txt");
File f = new File(res.getFile());
// As InputStream
InputStream in = getClass().getClassLoader()
.getResourceAsStream("text/textfile.txt");
#Mark is correct. That is by far the simplest and most robust approach.
However, if you really have to have a File, then your best bet is to try the following:
turn the contents of the System property "java.class.path" into a list of pathnames,
identify the JAR pathname in the list based on its filename,
figure out what "../.." is relative to the JAR pathname to give you the "project" directory, and
build your target path relative to the project directory.
Another alternative is to embed the project directory name in a wrapper script and set it as a system property using a -D option. It is also possible to have a wrapper script figure out its own absolute pathname; e.g. using whence.