Gradle - add directory to classpath - java

My application requires that a \config directory be available on the classpath when it looks for configurations files under the directory. I currently have dependencies configured like so, though this is probably not the correct way to make a directory available to my application:
dependencies {
... //runtime, compile dependencies pulled from repositories
runtime files('config')
}
I am using the application plugin to create a standalone zip for my project. If my \config directory has \config\subdir, file1, file2, then the plugin produces a build\install directory with the following structure:
| build
| --|install
| ----|bin
| ------ projectName
| ------ projectName.bat
| ----|lib
| ------ dependency1.jar
| ------ dependency2.jar
| ------|subdir
| ------ file1
| ------ file2
This does not work for my application because it explicitly expects a \config directory
However, this is the directory structure that I need:
| build
| --|install
| ----|bin
| ------ projectName
| ------ projectName.bat
| ----|lib
| ------ dependency1.jar
| ------ dependency2.jar
| ----|config
| ------|subdir
| ------ file1
| ------ file2
How can I make gradle add another directory to the build and specify it as part of the classpath for the generated startup scripts?

The application plugin documentation says:
Static files to be added to the distribution can be simply added to src/dist
I would try putting your config directory into src/dist/lib and continue adding it to your classpath with runtime files('src/dist/lib/config')
Note: working around this defect means that config has to go into /lib under src/dist

You may try this:
project('project-name') {
apply plugin: 'application'
mainClassName = "your.main.Class"
startScripts {
classpath += files('src/dist/lib/conf')
}
More information can be found here.

jar {
manifest {
attributes('Class-Path' : '<directory>' )
}
}
The above worked for me

Related

For a Main-Class in a JAR Subfolder, what is the correct setting for "Class-Path:"?

I have a JAR structured like this:
myHello.jar
|
+-- folder
| |
| +-- mypackage
| |
| +-- Hello.class
|
+-- META-INF
|
+-- MANIFEST.MF
That is, the Class mypackage.Hello is in the subfolder folder.
I've tried all manner of values for Class-Path: in the Manifest, but I always get...
Error: Could not find or load main class mypackage.Hello
Currently, the Manifest looks like this:
Manifest-Version: 1.0
Class-Path: folder/
Main-Class: mypackage.Hello
All the JarFile Spec says is this:
"The value of this attribute specifies the relative URLs of the extensions or libraries that this application or extension needs."
How can this be done using a subfolder?
(no I do not want to put it in the Root & use the usual value ".")

Java images loaded in ide but not built jar

I have my file path as follows:
+------------+ +-----------------+ +------------------+
| | | | | |
| src +-----------> com +--+---> application |
| | | | | | |
+------------+ +-----------------+ | +------------------+
|
| +------------------+
| | |
+---> resources |
| |
+------------------+
My code is in the application folder and my pictures that I want to load are in resources.
Im using the following code to get the images from resources onto a class in application (image is a BufferedImage).
image = ImageIO.read(new File("./src/com/resources/Pad.png"));
This seems to work in my IDE (intellij) as I can see the loaded images as shown
However, when I build, the images aren't being shown. I'm building by:
File -> Project Structure -> Artifacts -> Green plus -> JAR -> From modules with dependencies -> my main class location -> Extract to target Jar
Then I Build Artifact -> Build.
So when I go to the destination of the built jar and run it none of the pictures are being shown
I checked to see if the images were in the built jar by extracting the jar which does contain the pictures but for some reason the code isn't loading the picture.
You can try to use resourse as a stream instead of file.
image = ImageIO.read(this.getClass().getClassLoader().getResourceAsStream("com/resources/Pad.png"))
The src path is not available in build jar. You should use class loader to load resources from classpath. E.g. (assuming that 'src' is classpath root)
image = ImageIO.read(new File(this.getClass()
.getResource("com/resources/Pad.png").getPath());
Edited with the #MadProgrammer suggestion.

How to setup gradle distZip task to put resources into sub-directories and classpath correctly?

I have these build.gradle files:
dependencies {
runtime files('src/main/resources')
runtime files('src/main/resources/cfg')
runtime files('src/main/resources/sql')
}
jar {
exclude 'cfg/*'
exclude 'cfg/'
exclude 'sql/*'
exclude 'sql/'
}
And this one
dependencies {
runtime files('src/main/resources')
runtime files('src/main/resources/cfg')
runtime files('src/main/resources/fxml')
runtime files('src/main/resources/icons')
}
jar {
exclude 'cfg/*'
exclude 'cfg/'
exclude 'icons/*'
exclude 'icons/'
exclude 'fxml/*'
exclude 'fxml/'
}
startScripts {
doLast {
def winScriptFile = file getWindowsScript()
def winFileText = winScriptFile.text
winFileText = winFileText.replaceAll 'set CLASSPATH=.*', 'set CLASSPATH=%APP_HOME%\\\\lib\\\\\\*;%APP_HOME%\\\\lib\\\\cfg;%APP_HOME%\\\\lib\\\\fxml;%APP_HOME%\\\\lib\\\\icons;%APP_HOME%\\\\lib\\\\sql'
}
}
I can exclude the resource directories and their files from the projectName.jar file but I am not able to exclude the files from the sub-directories from the /lib directory which the distZip/distTar tasks create.
I want to have this layout in the zip/tar
projectName/
|
|-lib/
| |
| |-cfg/
| | |-*.*
| |
| |-fxml/
| | |-*.fxml
| |
| |-icons/
| | |-*.ico
| |
| |-sql/
| | |-*.sql
| |
| |-*.jar
|
|-bin/
|
|-projectName.bat
Where all resources in the sub-directories are not included in the lib directory and the sub-directories are set in the CLASSPATH variable in the projectName.bat so that the application is able to load all resources.
I was able to figure it out, I had to give the resources like this which puts the sub-directories in the lib directory
dependencies {
runtime files('src/main/resources')
}
and this change:
- winFileText = winFileText.replaceAll 'set CLASSPATH=.*', 'set CLASSPATH=%APP_HOME%\\\\lib\\\\\\*;%APP_HOME%\\\\lib\\\\cfg;%APP_HOME%\\\\lib\\\\fxml;%APP_HOME%\\\\lib\\\\icons;%APP_HOME%\\\\lib\\\\sql'
+ winFileText = winFileText.replaceAll 'set CLASSPATH=.*', 'set CLASSPATH=%APP_HOME%\\\\lib\\\\\\*;%APP_HOME%\\\\lib;%APP_HOME%\\\\lib\\\\cfg;APP_HOME%\\\\lib\\\\fxml;APP_HOME%\\\\lib\\\\icons;APP_HOME%\\\\lib\\\\sql'
This was missing: %APP_HOME%\\\\lib;
It's needed because the fxml resources are referenced like this in the source code:
getClass().getResource("/fxml/somelayout.fxml")
It looks for the resource on the CLASSPATH in the lib/ directory. This was missing.
You could add a new source set that is not included in the project's JAR file:
sourceSets {
dist {
resources {
srcDirs=['src/main/dist']
}
}
}
This source set contains the dependencies needed for the actual distribution. The folder structure under src/main/dist needs to rebuild the desired structure of the distZip artificat and will automatically be part of the ZIP/JAR:
src/main/dist
└ lib
├ cfg
│ └ …
├ sql
⁞ └ …
To add the resources to the application's classpath in the generated start script, you can to this:
startScripts.classpath.add(files('\"')).add(files('cfg')).add(files('sql'))
This will add %APP_HOME%\lib\., %APP_HOME%\lib\cfg and %APP_HOME%\lib\sql to the classpath in your start script.

How to set Class-Path in Java manifest.txt

My project structure is as below
TestProject
|
|---- src
| |
| |---- package
| |
| |---- main.java
|
|---- externaLibs
|
|---- lib.jar
The manifest.txt is as below:
Manifest-Version: 1.0
Created-By: 1.7.0_06 (Oracle Corporation)
Main-Class: package.Main
Class-Path: ../externaLibs/lib.jar ./externaLibs/lib.jar /externaLibs/lib.jar externaLibs/lib.jar lib.jar (However I've tried these class paths to the lib.jar, none of them works)
Exporting my project with Eclipse, then, when executing the command: java -jar main.jar, the exception about being unable to find the external lib.jar always occurs:
Exception in thread "main" java.lang.NoClassDefFoundError: org/example/SomeClassInLib
The output jar structure is as below:
testproject.jar
|
|---- externaLibs
| |
| |---- lib.jar
|
|---- pasckage
| |
| |---- main.java / main.class / and so on...
|
|---- META-INF
|
|---- MANIFEST.MF
What is the problem with the manifest.txt ?
Thanks for help.
In eclipse when you export, there is an option to export as Runnable Jar File. You can use the library handling radio buttons in the wizard to choose how the dependencies are handled. With the first two options, the dependencies get added into your jar. The third option creats an output folder and places the dependency jars in an accessible location for your jar.

Create executable JAR from classes and images using Eclipse

I have the following folder:
Game Of Life
|_bin
| |_Board.class
| |_Frame.class (main class)
| ...
|_res
| |_playToolbar.png
| |_pauseToolbar.png
| ...
|_src
|_Board.java
|_Frame.java
...
How do I create an executable .jar containing every class and image, so that when I execute the .jar it runs the Frame class? I am using Eclipse.
I think it is best to put your pictures inside a package. This way, everything will be packaged and loaded from your JAR file.
Afterward you will have to load your images using the getResource(...) method from an instance of Class.
You will have something like this:
GameOfLife
|- src
| |- my
| | |- company
| | | |- app
| | | | | Board.java
| | | | | Frame.java
| | | | |- resources
| | | | | |- playToolbar.png
| | | | | |- pauseToolbar.png
Then to create an ImageIcon of "playToolbar.png" from the Frame class you will have to use:
new ImageIcon(Frame.class.getResource("resources/playToolbar.png"));
Or:
new ImageIcon(Frame.class.getResource("/my/company/app/resources/playToolbar.png"));
If you are using Netbeans GUI builder, it can load resources from package without any problem.
To autorun your Frame class you have to create a MANIFEST.MF file and put it inside a folder named META-INF at the root of your JAR. Inside, you can define Frame as the Main-Class:
Manifest-Version: 1.0
Main-Class: my.company.app.Frame
Eclipse can do this step automatically if you select export->Runnable Jar.
If you are using eclipse, you can do a Rightclick->Export on the project and select Runnable Jar File under Java. Your res folder has to be configured as a source Folder in eclipse, otherwise it wont be exported.
You also have to regard that Loading the images may be different once they are packed in a jar file. See this for more information

Categories

Resources