How do I build an OpenFire plugin using Gradle in Intellij? - java

According to the OpenFire documentation (https://www.igniterealtime.org/builds/openfire/docs/latest/documentation/plugin-dev-guide.html) to build a custom plugin I need to create a jar with the following folder structure:
myplugin/
|- plugin.xml <- Plugin definition file
|- readme.html <- Optional readme file for plugin, which will be displayed to end users
|- changelog.html <- Optional changelog file for plugin, which will be displayed to end users
|- logo_small.gif <- Optional small (16x16) icon associated with the plugin (can also be a .png file)
|- logo_large.gif <- Optional large (32x32) icon associated with the plugin (can also be a .png file)
|- classes/ <- Resources your plugin needs (i.e., a properties file)
|- database/ <- Optional database schema files that your plugin needs
|- i18n/ <- Optional i18n files to allow for internationalization of plugins.
|- lib/ <- Libraries (JAR files) your plugin needs
|- web <- Resources for Admin Console integration, if any
|- WEB-INF/
|- web.xml <- Generated web.xml containing compiled JSP entries
|- web-custom.xml <- Optional user-defined web.xml for custom servlets
|- images/
I know there is an Ant build script to help do this but I couldn't find it and I'm having a hard enough time with Gradle and Maven, I'd rather not add having to learn Ant and deal with XML on to my list of chores. So, I tried to make a Gradle build script. Unfortunately Gradle still doesn't make any sense to me and in Intellij it seems to just do whatever it wants.
Regardless, this is the Gradle script I came up with.
task buildPluginJar {
group 'build'
description 'Builds OpenFire Plugin Jar'
println 'Clean old libs and classes.'
delete 'pluginDefinition/lib/*'
delete 'pluginDefinition/classes/*'
println 'Copy libs.'
copy {
into 'pluginDefinition/lib'
from configurations.runtime
}
println 'Copy classes.'
copy {
into 'pluginDefinition/classes'
from 'build/classes'
}
println 'Build jar.'
String outputPath = 'build/out/' + project.name + '.jar';
jar {
into outputPath
from fileTree('pluginDefinition/').include('**/*').collect { zipTree it }
}
}
I managed to get the file copying to work, but the end where it's supposed to put it all into a signal jar isn't working. It completes but there is no jar output. What am I doing wrong?

I could not figure out how to do this with Gradle. But I did figure out how to build jars with Intellij. I followed this tutorial:
http://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/
I went through the File > Project Structure menu and added two artifacts. One to build the jar with all of the java code in my pluginDefinition/lib folder, and another to build a jar with the full contents of the pluginDefinition folder that I could install on my Openfire server.
Still, it would have been nice if I could have done this with Gradle.

Related

How to put resources outside of classes package tree?

I want to deploy (create myapp.jar and from this .jar create myapp.exe file for installer) a java swing application.
I have a some packages:
resource package (net.myapp.ui.resource) inside i have .png, .wav, ... files)
output report package (net.myapp.ui.jasper.output.report) inside i have exported files (report1.pdf, report2.pdf, etc.)
config package (ne.myapp.ui.config) which contain config.properties file which can by updated after app have been installed because this file contain **persistence.xml** properties to create an EntityManagerFactory dynamically depending on the database server info.
From NetBeans IDE i can run app and it's work without problem; but when I build app, a .jar file is created: in dist directory i only have :
--> myapp.jar
--> lib folder
So i'm unable to access config.properties to setup database server IP and other parameters to be used in persistence.xml at runtime.
The question is : How do not put resources, output report, config ... in the classes package tree, but outside and access every resource from code using getResources() or getResourceAsStream() or ClassLoader ?
I want this strucure (after netbeans project build):
dist (folder)
/myApp.jar
/lib/lots-of-jar’s
/config/config.properties
/resources/my_cat.jpg
/output/report/report1.pdf, ...
....
Thank you for your help.

Files cannot be found when relative to property file in Java/Gradle

My Java project uses Gradle. I'd like to include a configuration folder conf when distributing the application with the task distZip.
This is an excerpt from my current project structure.
src
|-- dist
|-- conf
|-- application.properties
|-- keystore.jks
|-- truststore.jks
The conf folder is successfully distributed.
In my main() I load the properties with new File("src/dist/conf/application.properties") which works fine.
The application.properties contains two properties:
keystore.location = ./keystore.jks
truststore.location = ./truststore.jks
When starting the application from IntelliJ it works finde but when starting the distribution it cannot find the keystore.jks and truststore.jks because src/dist/conf does not exist but only conf.
How can I make sure that these files are found?
Your src/dist/conf folder is no resource folder for the java gradle plugin (and IntelliJ). It is just picked up by the application plugin (distZip task). IntelliJ sets the execution directory to the root path of the project. So it is just a coincidence that the src/dist/conf/application.properties can be read.
Move the files in from conf/dist folder to src/main/resources and they will be found by the processResources task and this folder should also be recognized by IntelliJ as a resource folder. Your classpath will have the resource node as root, so that you can use an absolute classpath to get to your files. (straight-forward sample: new File(YourClass.class.getResource("/dist/application.properties").getFile()))
I think that it will take much more effort to read the files in the conf/dist folders, because they are not part of the classpath.

Filepath in war

I created sigleton ApplicationConfig for settigs, that reads xml config file. But every time it fails on path to file.
hierarchy:
META-INF
src
--application
----config.xml
--engine
----ApplicationConfig
web
--WEB-INF
----web.xml
I've tried File f = new File("../application/config.xml"); but it gives C:\WebLogic\application\config.xml
It's usually a bad idea to store your configs in 'src'. It's better to separate your code and configuration. I suggest you to read about maven (or gradle).
Basic maven app has pretty simple structure:
src
--main
----java
----resources
where in 'java' folder you store your code, and in the 'resource' folder you store your configs. And now you have problem, because jvm is trying to find your file relatively WebLogic base folder.
And if you use maven, you could just write:
ApplicationConfig.class.getResourceAsStream("/config.xml")
Of course, in this case you should put your config into 'resources' folder.

Gradle change resource files target location in JAR

I am Gradle-fying a legacy project with the following structure:
root
+--- common
| \--- config
+--- module1
\--- module2
In the original project, config is just a folder that contains configuration files organized in subfolders for different environments. It contains a top level folder props and many subfolders as in:
config
\--- props
+--- prod
+--- dev
+--- john
\--- mike
The project can be configured to use any of the subfolders. The configuration gets loaded by a method that looks like this:
Config.class.getClassLoader().getResourceAsStream("props/" + ENV + "/" + name);
where ENV defines the environment (it's a system property), i.e., it can be prod, dev, mike, etc., and name is just the name of the file to load.
When running tests, I need to have the props folder in the classpath. When building the production artifacts (JARs and WARs) I wan't to avoid that and manually copy only the files I need in order to avoid possible conflicts or accidents.
So I decided to make config its own Gradle project and add it as a testCompile dependency to other modules that require configuration. However, if I add the props folder as a resource folder in Gradle, the generate JAR file for the config module will flatten all the subfolders of props (which is the intended behavior), and thus the code above will simply fail.
My question is: is there a way to tell Gradle to copy those files to a subfolder called props instead of to the root of the JAR?
I know it would be easy to refactor the project and move the folders around but we are in a phase of transition from legacy build and deployment tools and want to maintain the original structure as much as possible until we can switch to Gradle completely. It's an iterative process and can't happen overnight. So I need an interim solution.
Here's how I ended up doing it. This is the build.gradle file for the config module:
apply plugin: 'java'
sourceSets {
main {
resources {
srcDir 'props'
}
}
}
// this is to force Gradle to create the JAR used at
// runtime with the correct folder structure
jar.into('props')
idea.module.iml.withXml {
def node = it.asNode()
// this is to force IntelliJ to create the folders
// used at runtime with the correct folder ('package') structure
node.component.content.sourceFolder.#packagePrefix="props"
}
It works like a charm because the config module only contains resources in the props folder. Whew.

Customized ConsoleAppender in Eclipse RCP gives circular dependencies

I'm working on a Eclipse RCP application, and I would like to have a customized ConsoleAppender, so I can redirect all logs to the log window.
The log4j plugin and the log4j fragment (containing the log4j.properties) creates a unit which I manage to use successfully.
I've also created an 'extension' plugin containing my code to capture the log-data. Behold the 2 plugins and the fragment below.
rcp_external_log4j (plugin containing the jar file)
log4j-1.2.16.jar
rcp_external_log4j_fragment (containing the log4j.properties file)
log4j.properties (which points to VirtualConsol)
rcp_external_log4j_extension (plugin containing the VirtualConsol)
src/VirtualControl.java (which extends ConsoleAppender)
When I execute my project from within the Eclipse debug environment everything works fine. The VirtualConsole forwards all logging data as expected.
However, when I try to export the project with the 'Eclipse product export wizard' to a standalone executable I get the following problem:
Problem Occured
'Export Product' has encountered a problem.
A cycle was detected when generating the classpath
rcp_external_log4j_extension
rcp_external_log4j
rcp_external_log4j_extension
The VirtualConsole extends ConsoleAppender and is also called from other parts of the code.
The VirtualConsole is located in rcp_external_log4j_extension and uses log4j due to the extending of ConsoleAppender.
The rcp_external_log4j uses the rcp_external_log4j_extension, due to that the rcp_external_log4j plugin is bundled with the rcp_external_log4j_fragment, which refers to the VirtualConsole in the log4j.properties file.
Question: How can I write my own ConsoleAppender without getting a circular dependency? Can I put the code in the fragment? Can I put the code in the plugin containing the jar file (rcp_external_log4j)? I've tried those 2 attempts but without success...
Grateful for any help
Problem solved. src is put in the same plugin as the jar file.
rcp_external_log4j (plugin containing the jar file)
log4j-1.2.16.jar
src/VirtualControl.java (which extends ConsoleAppender)
rcp_external_log4j_fragment (containing the log4j.properties file)
log4j.properties (which points to VirtualConsol)
and 'src' added to the classpath of rcp_external_log4j. Seen in the MANIFEST.MF as
Bundle-ClassPath: log4j-1.2.16.jar,
src/
This way the VirtualConsole may be used both from the fragment and from the other code.
And the build.properties should contain:
jars.compile.order = src/
source.src/ = src/
output.src/ = bin/
for the code to be included in the exported product.
I don't think rcp_external_log4j_fragment needs to have rcp_external_log4j_extension in its build path, only in the manifest. This should remove the cycle.

Categories

Resources