I cloned a maven project from git and this was the initial class structure under the src folder:
src
|-main
|- java
|-com.controller
|- CommonController.java
Now, when I build this project, I don't understand how but the file name in which class is defined, changed to lower case and the folder structure is changing to below:
src
|-main
|- java
|-com.controller
|-commoncontroller.java
|- CommonController
and then IntelliJ throws this error since the file name has got changed:
java: class CommonController is public, should be declared in a file named CommonController.java
I searched a lot to find what is causing this but could not find any valid reason.
For other folks, this is not the case. So, I'm suspecting it's IntelliJ settings. Also, this issue is not for one codebase, I'm facing this problem with other projects as well. So thought to get it's root cause and fix it permanently.
Related
Here is the simplified structure of each module of my project :
src
|- main
|- java
<My classes>
|- resources
config.properties
|- test
|- java
MainTest
|- resources
I recently updated IntelliJ to version 2019.2. As Jetbrains removed the "uncheck create separate modules per source set" (see this post), when I import a Gradle project, I end up with one module having two sub-modules : main and test.
So, in Intellij project structure, I have this :
main sub-module
test sub-module
In some class, I load the config.properties file this way :
InputStream inputStream = MyClass.class.getClassLoader().getResourceAsStream("config.properties");
But when I run MainTest.main() in IntelliJ, which at some point calls the bit of code above, the resulting InputStream is null.
I guess that the test module classpath doesn't include the main resources folder...
How can I fix that ?
When I could check the box "uncheck create separate modules per source set", I had just one module, with one classpath, and my life was easier...
Is there a way, maybe using Gradle configuration in build.gradle file, to enforce one unique module/source set ?
IntelliJ 2019.2 defaults to delegating all build and run tasks to Gradle, so it shouldn't matter how you have structured the project in IntelliJ. You could also try running your test on the command line with gradle test to see if you get the same problem (which you should).
The 'test' runtime classpath does includes the resource folder from both the 'test' and the 'main' folder. So this also shouldn't be a problem.
In the screenshot you've shown of the main modules, there are no config.properties file in the resource folder. Did you put it in the META-INF sub-folder instead? If it actually is in the root of the resource folder, try referencing it with a slash (/) in the path, e.g.:
MyClass.class.getClassLoader().getResourceAsStream("/config.properties")
^^^
My code has gotten quite large and so I've decided to build a runnable JAR to see how it's done. I probably should've tried sooner because I'm getting 2 different errors related to the project structure, first is the "no main manifest attribute error" when trying to run the JAR from command prompt. Double-clicking the JAR does nothing (Win7). The second issue is related to the FXMLLoader explained lower down.
I followed the steps here to build the JAR, which involved moving all Maven files into the JAR directory. The compiled JAR gave me the manifest error, so I followed this which adds a Maven plugin in my pom.xml file. The error might be caused by a wrong naming convention with the line <mainClass>com.primary.Drag</mainClass> where primary is the package and Drag is my Drag.java file (class) which has the main method.
Inititally I was using the default package but read that this is not recommended for larger projects, so I put all my files into "primary". Here is my current hierarchy as shown in IntelliJ:
The problem is that ever since I created the "primary" package, I can no longer even compile the program via IntelliJ, let alone build a runnable JAR. This is due by the second error I mentioned, which is java.lang.IllegalStateException: Location is not set. on this line within primary/Drag.java:
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("firstlaunch.fxml")); It used to work with the default package, but not anymore.
I tried replacing firstlaunch.fxml with /primary/firstlaunch.fxml and /resources/firstlaunch.fxml (with and without moving resources into primary package) but no luck.
3 Related Questions:
Is my project structure incorrect?
How do I reference the fxml file from the primary package?
Is this what I should write in Maven's mainClass tags? <mainClass>com.primary.Drag</mainClass>
Is my project structure incorrect?
Answer:
Your package name should be like com.primary.******
How do I reference the fxml file from theprimary package?
Answer:
Always make sure that you are trying to load firstlaunch .xml from the class which is located in same package where that xml is kept. Means class which you wrote the loading code and xml file should be in same package
Is this what I should write in Maven's mainClass tags?com.primary.Drag
Answer:
If you package name corrected to com.primary , your main class Drag will correctly added by maven
I have a Java project and have to load resources such as sounds or images, which worked pretty well until I exported it into a jar file, where the app crashed because I it couldn't access the resources. I found after some research that I should use getClass().getClassLoader().getResource() or Class.getResource(). But after trying all the possibilities with the first or second function, with or without the leading /, but each time, I get null as a result, and used res/images/bg.jpg as argument. My project hierarchy looks like this:
|src
|Main.java
|res
|images
|bg.jpg
None of the solutions I've found on Stack Overflow or on Google worked for me. What am I doing wrong and what should I use?
EDIT
When exporting as jar, I am just right clicking on my project on Eclipse (without using any plug-ins), export and select runnable jar and explicitly declare my class Main as Classpath. When checking the content of the jar file, I can see the resources in the correct places.
The res folder should be a child of your src folder
|src
|Main.java
|res
|images
|bg.jpg
although standard practice would be to have the layout closer to
|src
| main
|java
|package
|Main.java
|resources
|images
|bp.jpg
The last time something like this happened to me, it was because my build did not copy the files into the jar. Might be worth doing a sanity check by listing the files in your jar:
jar tf /path/to/your.jar
I have a project structure like this:
src
|-main
|-java
|-com.abc.xyz
|-Login.java
I have to add a resource file to this and read the resource with
InputStream is = getClass().getResourceAsStream("launchers.properties");
This is giving null.
In Intellij I am not able to add a new package under src/main for resources folder so
that the project structure looks like this. How can I load the launchers.properties resource file into the project?
src
|-main
|-java
|-com.abc.xyz
|-Login.java
|-resources
|-com.abc.xyz
|-Login
|-launcher.properties
I tried the solution suggested by #maba but still not working
The launcher.properties should not be under a folder called Login. It should be placed directly in the src/main/resources/com/abc/xyz folder.
It is really as simple as I said but if the resources folder is not marked as a sources folder then this may be the problem.
This is the initial class and setup:
Now create the resources folder:
This newly created folder should be automatically marked as a sources folder and if it is blue color marked then it is. Otherwise you'll have to mark it manually:
Now you'll be able to add packages to it:
And now you can add the file to it:
And rerunning the application will not give you any null value back:
And the package view will surely show the launchers.properties file as well:
As #maba pointed out, your properties file should be in the same package as your class for your code to work.
So, you should have two files:
src/main/java/com/abc/xyz/Login.java
src/main/resources/com/abc/xyz/launcher.properties
If IntelliJ is showing the resource or not is beside the question. What you need to do is check if the results are included in your target artefact.
Do a build all in IntelliJ, open up the resulting WAR/JAR/EAR with your favorite ZIP viewer and browse into the "com/abc/xyz" folder. You should see both files there.
If they are, you are doing something wrong in your code. Check for typos, especially dots and spaces at the end or beginning (e.g. "launcher.properties[space]"), copy/paste the file name to make sure
If they are not there, your IntelliJ setup is wrong. Resources do not get included in your target build. Check online for tutorials how to do this with IntelliJ idea.
Follow these two steps
1) Create a directory
Right Click ==> New ==> Directory
2) Mark Directory as Resources Root
Right Click on the Direcory ==> Mark Directory as ==> Resources Root
No..... the structure is wrong.... you should not create the same package under resources, that is ugly and not proper: resources is for resources, and should not contain source packages.
When using ClassLoader.getResources(asStream)(path) method, the method just starts searching from the root of the classpath and the path name cannot start with / as leading characters. What you have to do, is to mark the resources as resources folder in IntelliJ. Then the files under resources will be listed under classpath and you can easily use them like you have done.
(I see in previous answers this option is not available yet in 2013, you only have mark as source folder, just like in Eclipse till now we have "add source folder", but now in 2018 it is available in Intellij: you can mark a folder as source, resources, test source, test resources, and all of them will be add to the root of classpath. )
I had the same problem and noticed that the resource file, for example: my.properties is not copied to the corresponding module folder in the target directory after build occurres. In order to solve that, I had to instruct Maven to copy the resources from the module directory to the target directory during the build process. In the .pom file I added <resource> element like that:
<project ...>
...
<build>
...
<resource>
<directory>src/main/java/com/abc/xyz</directory>
<targetPath>com/abc/xyz</targetPath>
</resource>
</build>
...
</project>
Note that the <directory> element is relative to the location of the .pom file , i.e. the root directory of the project, and the <targetPath> element indicates the package name separated by slashes.
from menu Run/edit configuration
in VM option you should add
-Dspring.config.location=path-file
I've tried it in IntelliJ, and it works!
Only solution worked for me:
File -> Project Structure -> Modules -> Dependencies Tab -> + Sign -> JARs or directories -> select resources directory -> Classes
Using the ClassLoader#getResource(), I need to access a file that is present in a project other than the one where my current code resides. How can this be done?
I'm using eclipse.
Directory Structure:
Root
|-project1
| |-package
| |-myResourceFile
|-project2
|-package
|-myCodeFile
I'm trying to get myResourceFile from myCodeFile, using myCodeFile.class.getClassLoader().getResource("../../project1/package/myResourceFile") but its always returning null. I do not want to add project1 to the classpath of project2. Though adding that also did not work.
With regards,
It's a bad idea to attempt to read files from another project like that because it ties you to exactly that directory structure. You already did the first step in decoupling the projects by using getResource() instead of using the java.util.File API so you can go the full way as well.
In Eclipse you can add other projects to a projects' build path (Project Properties -> Java Build Path -> Projects). You should be able to read the other projects' files now.
If you are using maven, then you can specify project1/package as a resource folder in the pom.xml of project2. You can theen use Classloader getResource method to get the resouce
http://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html