My project has the following directory structure:
Projects
|---------A
|---B
|---C
Project C uses src files of B. In eclipse I import project A and classpath file present under A contains B's and C's source folder as classpathentry src. Thus, even when I am on any of C's java file which uses variables declared in B's java file, I am able to navigate to them using Ctrl+Click on the variable.
Now my requirement is to move out C to the level of project A:
Projects
|--------A
|---B
|--------C
Now A and C will have different classpath files. When in C's classpath file I try to give relative path of B's source folder. I get the following error in eclipse:
Illegal entry in '.classpath' of project 'B' file: Path for IClasspathEntry must be absolute
I tried out creating a jar of B's source file and giving the classpathentry of the jar in C's classpath file. But, with this approach , I loose out being able to navigate to B's java file from C's java file using Ctrl+click.
I cant give absolute path because the code is shared and different systems will have different path.
So, how do I specify my project C's dependency on B's source folder in .classpath file so that I retain the navigation through Ctrl+Click
Related
I have a Maven project A (packaged as a pom) containing Maven module project B (packaged as a jar).
Project B is also physically in the root of project A.
When B is being built, a plugin indirectly uses my code (inside B) to access a property file in its src/main/resources location.
When I build project B directly (mvn clean install) the code can easily find that file by using new File("src/main/resources/foo.properties");
However when I try to build project A, it first will try to build the module B, and in that case it cannot find the property file.
Apart from the 'new File' variant, I have tried using
this.getClass().getClassLoader().getResourceAsStream("src/main/resources/foo.properties");
and I tried using Spring:
Resource resource = new ClassPathResource("src/main/resources/foo.properties");
Both also with a "/" prefix. But the file simply cannot be found.
Why is that? Might it be looking for the file in the root of A? Is it possible to find the file in module B when building A?
Thanks!
new File("src/main/resources/foo.properties");
This is a path relative to the working directory. The working directory is wherever you called maven. So that's why it won't work when calling maven anywhere other than the directory of module B.
this.getClass().getClassLoader().getResourceAsStream("src/main/resources/foo.properties");
This won't work because the classpath is where maven put the classes, that is, target/classes.
What you need to do is add this file as resource in the maven build, then use the getResourceAsStream idea with the correct path. Since you used the standard maven layout, you probably don't need to anything and just use
this.getClass().getClassLoader().getResourceAsStream("foo.properties");
I want to access the resource's form of my project "\src\main\resources" but for any reason I can only access the target classes.
Here is my code:
System.out.println(Main.class.getResourceAsStream("/123.txt")); // java.io.BufferedInputStream#66cd51c3
System.out.println(Main.class.getResource("/123.txt")); // file:/C:/Users/Raul/workspace/Serial/target/classes/123.txt
System.out.println(Thread.currentThread().getContextClassLoader().getResource("123.txt").getPath()); // /C:/Users/Raul/workspace/Serial/target/classes/123.txt
and here my Project Dirs:
The thing is, even if I delete all the files in the target/classes and run the code, the compiler will copy the files from "src/main/ressources" into "target/classes" and read them from there.
I want to access the resource's form of my project "\src\main\resources" but for any reason i can only access the target classes.
I think the question is answered by user #VGR. Just to clarify it in another words:
You put your resources in the /src/main/resources folder, and these resouces will be copied as is into the /target/classes folder when you build your project.
Example
src/main/resouces/123.txt -> target/classes/123.txt
src/main/resources/myresources/145.txt -> target/classes/myresources/145.txt
...
Now if you run the program inside of your IDE you'll observe the following:
System.out.println(Main.class.getResource("/123.txt"));
output: file:/C:/Users/Raul/workspace/Serial/target/classes/123.txt
System.out.println(Main.class.getResource("/myresources/145.txt"));
output: file:/C:/Users/Raul/workspace/Serial/target/classes/myresources/145.txt
But if you open the generated jar file you'll not see the target folder because the file 123.txt will be on the root of the jar file and the file 145.txt will be under the folder myresources/145.txt.
The folder target is just an output directory for the build tool and will not be packaged within your jar file.
Now to the following question:
the problem is that i dont know how to export the target classes to my jar, or how can I get "src/main/ressources" as return value.
To answer this question you have to look into your pom.xml file on the root of your project. There should be a <packaging>jar</packaging> entry in it. If that is so you create the jar file as follows:
Option 1: from the command line
mvn clean install
the jar file will be created and copied into the folder target.
Option 2: from within Eclipse (for example)
right click on the pom.xml > Run AS > Maven install
the jar file should also be generated and copied into the folder target.
Note: on your screenshot there are two jar files: core-0.0.1-SNAPSHOT.jar and Serial-0.0.1-SNAPSHOT.jar; remove them (mvn clean or right click > Run AS > Maven clean) before generating the jar file. The reason is Maven can only generate one jar file per Maven module / project, afaik.
You are seeing the intended behavior. A Java program is compiled into an executable form—meaning, .class files and resources. When other users run your program, they will not have access to the source, so your code should not assume your source tree will be available.
Simply put, your code is correct as is. Do not attempt to read the source tree. If you want target/classes to contain up-to-date files, rebuild your project.
A word of caution: Never use the getPath() method of URL to convert a URL to a file name. There are many characters which are not permitted in URLs, and those characters will be “percent-escaped” in order to conform to the URL specification; as a result, the path portion of a URL is not a valid filename! The only correct way to convert a URL to a file is Paths.get(url.toURI()). However, you should not even try to convert a resource to a file at all, because once you move on to packaging your programs in .jar files, your resources will not exist as regular files at all, only as entries in .jar files (which are actually just zip files with some Java-specific entries added).
I use maven to create a runnable jar from multiple projects :
Project A (contains the Main class):
/src/main/resources/META-INF/resources/a.txt
Project B (depends on Project A):
/src/main/resources/META-INF/resources/b.txt
Runnable.jar (create with mvn):
/src/main/resources/META-INF/resources/a.txt,/src/main/resources/META-INF/resources/b.txt
In the Main class I use Class.class.getResource to get the content of a.txt and b.txt.
When I do java -jar Runnable.jar, I can access to a.txt and b.txt. But if I run it from Eclipse, I can only access to a.txt . Is it possible to get it right? I'd like to change resources content when the application is running and get the result without recompiling.
The Run configuration :
[MAIN] => Project : Poject B, Main class : Main
[ClassPath] => UserEntry : Project A, Project B
NB : If I change the order of the UserEntry, I can access to b.txt but not a.txt.
Could you help me?
Project B needs to be added to Project A's Java Build Path. Open up project A's Properties dialog and do so.
I've found a solution. I've created a linked resource folder in project B (B/src/main/resources-a) which refers to the resources directory of project A (A/src/main/resources). I set the new linked folder as a source directory. Now it works and I can see the resources contained in the Project A in the target/classes folder of Project B. It's exactly what I expected but if I'd like 'mvn eclipse:eclipse' automaticaly configure .project and .classpath files?
I added an external jar file into my eclipse project from the properties>libraries in my project. Then I export my project as a file system, to make runnable for every computer. However after I import to project in eclipse, jar file refers to the my computers path thats why it does not work.
How should I solve this ?
Thanks
Define a class path variable and refer to the JAR using a variable in the class path of your project. Each programmer can then set the variable according to theirs environment. Variables can be set in Window -> Preferences -> Java -> Classpath Variables and used by pressing Add Variable... in Java Build Path editor of your project. When adding a variable to classpath, you can even press Extend... and "extend" your variable with a suffix - i.e. have the variable contain a folder name and suffix it with a fixed file name.
Some more obvious options:
Copy the JAR inside your project, then export it.
Agree on a common workspace structure and use a relative path to refer to the JAR.
Use a dependency management tool (e.g. Maven).
I'm trying to recompile a project I've been working on and I keep getting an error message when trying to load a property file:
The system cannot find the path specified.
I guess this has to do with the classpath. But I've added the path to the file in Properties-> Java build path-> Libraries (external class).
I also checked the .classpath file generated by eclipse, and the path is really there!
Why isn't Eclipse looking at the right path?
There 2 different classpaths, build classpath and runtime classpath. The one you are setting is the build classpath.
Check your runtime classpath by going to Run -> Run Configurations and select your application configuration. Check the classpath setting there.
There is another workaround for this also. Eclipse by default will include your output folder (usually named bin) in your classpath. Typically anything that are not compilable in src folder will be copied to bin as is. I assumed your property file is not located in src folder. What you can do is to open your project property and add the folder where your property is located into Java Buld Path -> Source (tab). This way eclipse will copy the content of that folder into bin and will be in the classpath.
There are several ways to read a property file:
Have it in the current working directory (the one cd'ed to). You can do this in the Eclipse launch configuration. (Run -> Run...)
Include it in your application, by having it in a source folder. You then need to read it in through a class loader to be able to get it always (when jarred up, through Java Web Start, etc).
Double check if the property file or its directory is in the excluded list of the project Source. If it is remove the exclusion filter and try recompiling.