why the current directory not the target\classes? - java

Using maven for a project say myproject
it has the following myproject\src and myproject\target, and all the class and resources are copied to myproject\target\classes.
However i found the user.dir or current dir is still myproject, why not myproject\target\classes, how to change the current dir to myproject\target\classes?

Because maven always runs things in the working directory of the pom.xml, unless you configure it differently (which i think you can do in the surefire plugin which is what runs test cases).

If you want to get class folder path,you can following this code :
String path = YourClassName.class.getResource("").getPath();

Related

How to copy java package with Gradle

I am working with Gradle and I am trying to update/copy resources from one project to another. If I try
[...]
//copies resource bundles from root project
from ("cfg/resources") {
into "cfg/resources"
}
[...]
My package got copied to the cfg folder as expected like:
What I actually want to achieve is to keep my project structure like:
Any hint?
Once I created a Source Folder in my project with the given path cfg/resources, it looked as I wanted. Even after deleting everything and copying again. I am using Eclipse by the way...

How to get resources folder(files) from other maven module?

I have some amount of child maven modules in parent module.
How can I get access from one module to resources of another and to have this solution stable in jar file ?
I tried something like: (resource.txt - is situated in first module, and code is executing in second)
String pathToFirstModuleResource = ClassFromFirstModule.class.getClassLoader().getResource(resource.txt).getFile();
But it points me to ...firstmodule/target/classes/resource.txt, so it works almost good, but returns not a resource folder, but target/classes. Why it returns this targets folder, though should to return ...firstmodule/resources/resource.txt?
Why it returns this targets folder, though should to return ...firstmodule/resources/resource.txt?
No.
It looks like you configured resources being threaded by your IDE as a souce folder.
Therefore the folder resources only exist in your development environment. At runtime the file is simply copied to the root of your jar, which merely is the content of target/classes.

Spring boot external properties file in "current directory" is ignored

from the manual:
24.3 Application property files SpringApplication will load properties from application.properties files in the following locations and add
them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
It mentions current directory twice but this really doesn't mean anything:
I tried putting it in the root of my project (i.e. above src in the folder that matches the output of java.io.File( "." ).getCanonicalPath() and System.getProperty("user.dir");), and I tried putting it with the war files (i.e. in build\libs)
But the only place to put it that actually works is the default location (src\main\resources).
So what does "current directory" even mean and where do the files really go?
I need to find the correct external location for the files so I don't have to build database credentials into the app.
The guides say that putting application.properties in current directory will work and I found the exact current directory to put it in but it still doesn't work, which I can verify by the output of: System.out.println(System.getProperty("spring.datasource.url")); which is null It does output the correct value only with an embedded properties file.
According to ConfigFileApplicationListener:
// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS =
"classpath:/,classpath:/config/,file:./,file:./config/";
file:./ resolve to the working directory where you start the java process.
I agree with Stephane Nicoll's argument that we generally don't need this for development and test but needed for production where properties file is generally externalized and the one present in source code is not used. This is what works for me ,
java -jar myjar.jar --spring.config.location=file:D:\\RunRC\\application.properties
Directory - D:\\RunRC - mentioned in above command is sample from my machine.
I keep using properties file of source code i.e. from \src\main\resources\ in development and test but in production , I comment out entries and if I am starting my jar or war from D:\\RunRC then I provide Current Directory as shown in above java command and keep properties file there.
Just doing - #PropertySource({ "application.properties"}) or #PropertySource({ "file:application.properties"}) doesn't pick it up from the directory where jar or war is kept.
For database credentials, I would suggest to use OS specific environment variables and use syntax similar to - #PropertySource({"file:${CONF_DIR}database.properties" }) where CONF_DIR is existing environment variable pointing to that directory.
Hope it helps !!
I understand that the current directory is the root directory of your project. However, you can change this with -Dspring.config.location=your/config/dir/.
Have a look at this post enter link description here
If you search for "current directory java", you'll end up here with this question. The intention is that if you put an application.properties in the same directory as the application, it will be picked up by default.
You will not use that feature in development or for test as you shouldn't rely on that feature. But when running your app in production, it might be handy to put environment-specific settings in a configuration file that sits next to the application itself.
Current directory refers to where we execute our jar. Creating an executable jar via Spring Boot maven plugin and placing application.properties just beside the jar file will work. An example :here

Opening a xml file from eclipse and from a .jar file in java

Yesterday, I had a problem because I couldn't manage to open a xml file (it owuld give me a FileNotFoundException) located in the ressources folder of my .jar file, which I managed to open on eclipse using the following lines of code. You can see my old problem here. This was my code with the problem :
File xmlFile = new File("ressources/emitter.xml");
ConfigurableEmitter emitter = ParticleIO.loadEmitter(xmlFile);
Someone told me it that one way was to use getClassLoader().getRessourceAsStream method to open a xml file in a .jar file that was exported
InputStream i= this.getClass().getClassLoader().getResourceAsStream("ressources/emitter.xml");
ConfigurableEmitter emitter = ParticleIO.loadEmitter(i);
Unfortunately, that solution only works when I export my project into a .jar file, so if I want to go back debugging my program, I have to take the old code that would only works on eclipse.
My question is: is there any better way to do this without having to change my code if I want to export it or if I want to debug it?
Thank you
edit :
Thank you all, it works perfectly fine now
my problem was that I put my ressources folder like that :
+project
+src
+ressources
+emitter.xml
InputStream i= this.getClass().getClassLoader().getResourceAsStream("/ressources/emitter.xml");
The above should work in both cases (Note is is /resources/.... This is assuming say your directory structure is below:
MyProject
+src
+ressources
emitter.xml
Place the file alongside your source files, then you can use the getResourceAsStream() method in both cases. Don't forget to update the path (which should be the package name of your class, but with slashes instead of dots).
My question is: is there any better way to do this without having to
change my code if I want to export it or if I want to debug it?
Yes, use Maven. Maven will handle that and it hooks into Eclipse beautifully (NetBeans too!) What you do is place the resource in src/main/resources and then you can have Eclipse run the test goal of the Maven project or you can just run mvn test from the command line. Another advantage of using Maven here is that you can also have src/test/resources/emitter.xml which overrides the one in src/main with environment-specific test instructions and it won't affect your deployment.
InputStream i= getClass().getClassLoader().getResourceAsStream("ressources/emitter.xml");
or
InputStream i= getClass().getResourceAsStream("/ressources/emitter.xml");
(note the absolute positioning)
both work when the class is in the same jar, on the same class path.
In the jar the names must be case sensitive, but as the jar already works. Ensure that the ressources directory is on the class path too, or copied to the target directory.
As "ressources" is probably configured yourself (not named "resources" as in English), you probably need to add it to the build somehow.

Junit + getResourceAsStream Returning Null

Not sure how this is possible. I re-read up on getResourceAsStream and it's always returning null.
InputStream source = this.getClass().getResourceAsStream("test.xml");
Right next to test.java in the Finder (using OS X and Eclipse) is test.xml
I can open it in TextWrangler and view it as existing with data inside.
This is a Junit test if it makes any difference. I went and looked at existing Junit tests on our system and I'm using it in the exactly same manner as a working example (as in where the file is located and the code itself).
What small difference could there be preventing I assume getClass() from returning the right path?
It's not finding the resource on the classpath. If you are using junit and maven make sure the resources are copied on the target/test-classes by adding <include> file directive on <testResource> section
You can also find out the location of your class in the file system by using
this.getClass().getResource(".")
and checking to see if the resource is there
getResourceAsStream() is using the CLASSPATH, and as such it will load from wherever your classes are, not your source files.
I suspect you need to copy your XML to the same directory as your .class file.
In case you are using Maven, add this part to your pom.xml
<build>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
</build>
Your test.xml and other resource files must be located in src/test/resources
I always have problem with this method. Here are 2 links, which might be useful:
Describes diference between
getClass().getResource(); and
getClass().getClassLoader().getResource();
Simple utility which simplifies
these 2 approaches
I always experiment with adding "/" at the beginning or "./".
From my experience the best method is using FileInputStream. There is only one thing to remember (while using FileInputStream with Eclipse), with default settings, your working directory is set to projects root. You can always check where is your current directory (and what relative paths you need)using this piece of code.
Assuming test.xml is located right under your test root source folder, do this:-
InputStream source = this.getClass().getClassLoader().getResourceAsStream("test.xml");
I spent lot of time in this problem and it was missing me the following configuration:
Right-click on an eclipse project and select Properties -> Java Build Path -> Source and edit Included row and add *.properties (*.fileExtension)
try using classloader
InputStream source = this.getClass().getClassLoader().getResourceAsStream("test.xml");
Put test.xml in the src/main/resources (or src/test/resources).
File file = ResourceUtils.getFile("classpath:test.xml");
String test = new String(Files.readAllBytes(file.toPath()));
Try MyClass.getResourceAsStream().
Also try putting the test.xml in your classpath. For instance, in an Eclipse web project put text.xml in webcontent/WEB-INF/classes
From Java API:
http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getSystemResource(java.lang.String)
Find a resource of the specified name from the search path used to load classes. This method locates the resource through the system class loader
So the syntax will for instance be:
ClassLoader.getSystemResource("test.xml").toString();
Works like a charm!
Seems there are a lot of possible causes to this and mine was not found here. I figured out that my tests were no longer being detected/run by maven and this baeldung post also provided a lot of possible causes. My problem ended up being that at some point I altered the wrong pom and set my packaging to pom.
The test-compile step was being skipped completely and no new resources were ending up in the classpath. So, check your target/test-classes directory and make sure that your tests are actually compiling in the first place.
I got a Similar issue. The problem in my case was that getResourceAsStream() was working fine for the main Application code but giving Null in case of unit-test. The problem was that for the main Application code it was looking in the target/classes folder for the file but for the unit-test it was looking in the target/test-classes. I fixed the problem by adding my file in the test/resources folder.
Add the folder that your having your resource files in to the source folders of eclipse. Then the file should be automatically put in the bin directory.
You need to put the copy of your resource file to the test resources, in my example it is font file:
Then call next from your jUnit test:
public static InputStream getFontAsStream() throws IOException {
return Thread.currentThread().getContextClassLoader()
.getResourceAsStream("fonts/" + "FreeSans.ttf");
}
I had this problem with a Spring class. System.class.getResourceAsStream(...) worked in unit tests but not in Tomcat, Thread.currentThread().getContextClassLoader().getResourceAsStream(...) worked in Tomcat but not in unit tests.
Ulitimately I went with:
ClassUtils.getDefaultClassLoader()
.getResourceAsStream("com/example/mail/templates/invoice-past-due.html"))
I also found that once I did it this way, I did not need to have the path starting with a slash.

Categories

Resources