Using Intellij, Springboot.
When I rename the files in a directory manually(Intellij->refactor->rename) and restart my web application, when I walk in that directory I can see the renamed files are duplicated (there now is both old name and new name in my app)
What am I missing?!
my directory is under /resources/my_dir
File myDirectory = new ClassPathResource(MY_DIR).getFile();
try (Stream<Path> paths = Files.walk(queryDirectory.toPath())) {
paths.filter(Files::isRegularFile).forEach(path -> setFile(path));
}
I'll assume here, that you are talking about files in the directory of compiled files. The reason is that only the source files are renamed when renaming something like an XML file in the resources folder, or whatever the case may be.
That, however is not in any way tied to the target directory. Build tools, like maven, or I assume the compiler intellij uses copies everything it can't compile to that target directory.
What you have to do is clean the project and build again, so that the target directory is "clean"
Related
I've got two Maven projects A and B. I'm packaging project A as a jar and adding it as a dependency in project B. Project A shows up in my External Libraries (using IntelliJ) and I can see all the source code and files.
In project A I've got a method that is retrieving the files in a folder located at projectB/src/main/resources/folder/, and I'm using the following code to check whether any files exist within this folder:
File folder = new File("src/main/resources/folder/");
File[] defaultDefinitions = folder.listFiles();
This works correctly when project A is ran. However, when project B calls this method, instead of appending the path to project A's working directory, it is appending it to project B's, and obviously there are no files located at projectA/src/main/resources/folder/.
How does one go about solving this issue?
The problem you're having is that you're using a relative path, and you're relying on working directories (automatically managed by the IDE). You need to read files in a way that's going to be predictable, even if you run your code outside the IDE.
You can solve the problem by using absolute paths, which is going to help even if you run the program from the command line, or anywhere outside the IDE:
String path = "/absolute/path/from/properties/etc/folder/";
//better use a program argument or properties file for this
File folder = new File(path);
Don't load Maven resources from the filesystem API :
File folder = new File("src/main/resources/folder/");
It will work only during the development phase as you have the source code besides the running application.
Instead, use the classloader :
File folder = getClass().getResource("/folder").toURI().toURL().getFile();
It will work as src/main/resources is a "special" directory for Maven as all resource files located in this directory are added in the classpath at compile time and will be also available in the classpath at runtime.
Note that you could retrieve the File from a less convoluted way by using the java.nio API :
Path folderPath = Paths.get(getClass().getResource("/folder").toURI());
Stream<Path> pathStream = Files.list(folderPath);
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 have xml files in eclipse project's source directory, like:
src/java/main/com/xx/zz.xml
1.When using eclise to build automatically, xml files are copied to target/classes.
2.When using 'mvn complie', xml files are not copied to target/classes.
For the second case, I found this:why xml files in eclipse project's source directory is not copied to target/classes directory?.
but for the first case, I cannot find any document.
Can someone explain it for me ?
Thanks!
Eclipse works quite a bit differently than standalone Maven. Maven uses javac from JDK. By default javac only processes .java files and generates .class files in the same directory as .java sources. Maven asks it to generate classes in a separate directory and javac only moves .class files there.
The reason for this is that javac gives you more freedom in organizing your source files than most developers use. For instance javac does not care if your class is located in a folder structure that mimics declared packages. You can put a module together by putting several .java files along with some other files like .properties or .xml in the same folder. Your .java files can have different package declarations. For instance you can have files A.java:
package aaa.bbb;
class A {}
and B.java:
package zzz.uuu;
class B {}
If you ask javac to put classes in a target directory, it will create necessary subfolders for .class files, that will resemble the package structure. However it cannot do so for properties and xml files, because they do not contain package declarations. Such 'resource' management is left for the build tool.
Maven expects that you put such resources in another source folder (resources). They will be copied to generated package structure, so you should match it in resource folder. This is why it does not copy non-java files in source folders.
Eclipse expects you to put even .java files in a target package structure and complains if your package declaration does not reflect relative path of the file. This is where you have less freedom compared to bare javac. Thanks to this rule it can copy resources along with .class files and does not need another 'resource' folder.
You can configure Eclipse to use source folder as output folder. Eclipse will not touch resources in this case.
If you right click on the project in eclipse and select 'properties', then Java Build Path you see an input at the bottom for the Default Build Path, which should be target/classes. The source folders are shown in the main dialogue. If you click on the source folders then you can modify each, to exclude the xml files (if that is what you want to do).
Maven will include your xml files automatically if you put them in src/main/resources.
If you don't want to have xml files in build directory, you need to configure eclipse excluded source file types -
right-click on the file in the Project Explorer, choose Resource Configurations > Exclude from Build and choose the configurations that you want.
Not sure this basic question has already been answered on SO.
From the reference and also answers found on SO, I understand that in Eclipse a "source folder" is a folder that JDT will search for source files, and compile them.
It has been mentioned also that each source folder may have a counterpart to store compiled classes. Maybe this is why the content of the usual "src" folder of a project is compiled into a "bin" folder (when using such src/bin project option in Eclipse).
Question: Where to store additional non-source files, e.g. an icon, a security policy, or a data file? I guess this is in a "regular" folder, but at which level in the project hierarchy (usually)? Is it possible to put it in a source folder or not (why would we do that)? What happens after compilation, or export to a .jar file, under which conditions are the files copied in the .jar? Is the relative path preserved?
This is purely conventional. You can store them all in src if you want.
However, if you want to stick to Maven or Gradle conventions, then you should have something like that:
src/main/java : main source file, that will be compiled and then distributed (jar, etc)
src/main/resources : main resources, distributed.
src/test/java : test source file, aka Junit test
src/test/resources : test resources.
Maven would compile all Java into target/classes and copy all resources into target/classes. For test, it would be target/test-classes.
Beside, if you want to access a resource, that in the Jar where your classes are, you should not use new File("...") or Paths.get(...) but getResourcesAsStream or its counterpart getResource:
try (Scanner scanner = new Scanner(MyClass.class.getResourceAsStream("/myfile.txt"))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
This would probably throw a NPE if /myfile.txt was not found.
When I clean and build a project in NetBeans, the .jar file appears in the dist folder, like it's supposed to. But what if I have multiple files under the project? What happens to those files? E.g. I have a Game project, and under it are the different characters(knight, rogue, etc.) but I only see a game.jar file when I clean and build, I want to know what happens to the individual files. Thanks
Those files should be in the jar file as compiled .class files. It's easy to double check what's in the jar file since it's in zip format. You can use a program like 7-Zip to open it, or rename it to the zip extension (e.g. from mygame.jar to mygame.zip) and whatever OS you're using probably has some way to open it.
When you open or extract the jar file you'll find the compiled class files in a directory structure that reflects your package structure. For example, if you have Knight.java in the directory src/game/characters/Knight.java in the jar file you'll find something like classes/game/characters/Knight.class.
The name "jar" is an abbreviation of "Java archive". It stores all the classes and other resources (for example, images) in a project.
The classes you have defined in .java files will be compiled into .class files - these are contained in the .jar file.
All resources get compiled into the JAR file. If you want a separate JAR for the resources, you'll need to split the project into two maven projects: one jar for the code, one for the resources. You can then create a third project that would generate a distribution.
That's a lot of work, though. It's.a lot easier tO keep everything in one JAR unless you have explicit dynamic loading requirements.