Deploying a war with a MANIFEST.MF - Dependencies get ignored - jboss7.x

I am deploying a war into JBoss 7.x using Arquillian for testing and it has a dependency on Apache Commons Collections. However, it just doesn't seem to pick up the module dependency.
MANIFEST.MF
Dependencies: org.apache.commons.collectionss export
Arquillian Deployment
#Deployment
public static Archive<?> createDeployment() {
WebArchive archive = ShrinkWrap.create(WebArchive.class);
archive
.addPackages(true, "com.example.package")
.addAsResource("META-INF/MANIFEST.MF", "META-INF/MANIFEST.MF")
// * Tried the following two options with no luck
//.AddAsManifestResource("META-INF/MANIFEST.MF", "MANIFEST.MF")
//.AddAsWebInfResource("META-INF/MANIFEST.MF", "META-INF/MANIFEST.MF")
// * If I enable the following, it works fine. getLibrary just picks
// * up the lib through maven.
//.addAsLibraries(
// getLibrary("commons-collections:commons-collections:3.2.1"))
;
return archive;
}
I don't want to use jboss-deployment-structure.xml since it feels like using a sledgehammer to crack a nut.
Any ideas?

In my case I added a MANIFEST.MF within src/test/resources and .addAsManifestResource("MANIFEST.MF") for Arquillian
MANIFEST.MF
Manifest-Version: 1.0
Built-By: me
Build-Jdk: 1.6.0_45
Created-By: Maven Integration for Eclipse
Dependencies: org.infinispan export
Arquillian
#Deployment(testable = false)
public static WebArchive createDeployment() {
MavenDependencyResolver mvnResolver = DependencyResolvers.use(MavenDependencyResolver.class).loadMetadataFromPom("pom.xml").goOffline();
return ShrinkWrap
.create(WebArchive.class, "example.war")
.addPackages(true, Filters.exclude(".*Test.*"), "com/comapany/")
.addAsManifestResource("MANIFEST.MF")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
}

As it turned out, I asked this same question again (this time about Jar Files) since I forgot all about this question.
The solution has also since been discovered: (Same as from the other question)
The whole thing turned out to be a lot simpler.
Even with .addAsManifestResource OR .setManifest, the MANIFEST.MF was autogenerated by Maven.
This was resolved with the following section in pom.xml instead of using a custom MANIFEST.MF and using .setManifest("META-INF/MANIFEST.MF"); The MANIFEST.MF is auto-generated and there is no customised copy in the resources folder (to avoid confusion more than anything since it was ignored anyway)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>
org.infinispan,
org.infinispan.infinispan-tree export,
</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Related

Using MaterialFX in IntelliJ

I've been trying to use MaterialFX (which is a JavaFX design library (like jFoenix)) in IntelliJ but I didn't succeed to do so. I've added the required dependency:
Also, I've added the requires org.glavo.materialfx.adapter; in module-info.java:
module org.example {
requires javafx.controls;
requires javafx.fxml;
requires com.jfoenix;
requires org.glavo.materialfx.adapter;
opens org.example to javafx.fxml;
exports org.example;
}
Does anyone have an idea how can I use this library because the author didn't really explain well how to do so. I would like to mention that it works perfectly in Scene Builder's latest version so I just wonder why it doesn't do so in IntelliJ.
Use Maven (or Gradle) for dependency management
You are using Maven (at least that is what the screenshot shows in Idea, though it could be Gradle making use of a Maven repository).
You should define the dependency as a maven dependency in your pom.xml (or build.gradle) then reimport the build file into Idea.
You should not manually set library dependencies in Idea.
Idea and Maven will recognize that you have a modular project and, when you have the dependency defined in Maven, they will automatically put the new dependent module on the modulepath for compilation and execution.
The maven artifact can be found by searching the maven repository:
https://search.maven.org/artifact/io.github.palexdev/materialfx/11.13.5/jar
The dependency info is:
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.13.5</version>
</dependency>
The module-info for MaterialsFX requires VirtualizedFX. The VirtualizedFX module also needs to be on your module path. The pom.xml file for MaterialsFX has a includes a dependency on io.github.palexdev:virtualizedfx:11.2.6. So the dependent module will be accessible for your build and runtime automatically via Mavan and Idea's inbuilt integration with the Java Platform Module System.
Require the correct module name
The module name for the library is not org.glavo.materialfx.adapter, it is MaterialFX, so you should use:
requires MaterialFX;
NOT:
requires org.glavo.materialfx.adapter;
I recommend that you spend some time studying tutorials for your build tool and the Java Platform Module System.
Example app
Example was created by running the idea new JavaFX project wizard, then modifying the resultant project.
pom.xml
In addition to having a dependency for the MaterialFX library, you also need to have dependencies for both javafx-controls and javafx-fxml.
MaterialFX requires both of these transitively at build and runtime (even if you don't use fxml in your application).
The MaterialFX pom.xml does not have an explicit dependency configuration for JavaFX, so you need to define those dependencies in your project pom.xml (which you would want to do in any case to ensure that your application is using a specific JavaFX version).
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>material</artifactId>
<version>1.0-SNAPSHOT</version>
<name>material</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>18</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>18</version>
</dependency>
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.13.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<source>18</source>
<target>18</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
module-info.java
module com.example.material {
requires MaterialFX;
exports com.example.material;
}
MaterialApplication.java
package com.example.material;
import io.github.palexdev.materialfx.controls.MFXButton;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MaterialApplication extends Application {
#Override
public void start(Stage stage) {
stage.setScene(new Scene(new MFXButton("mfx")));
stage.show();
}
public static void main(String[] args) {
launch();
}
}

Maven Assembly Plugin is not setting the MainClass manifest setting

I have a maven project which generates a jar via the maven assembly plugin I want to run as a console app. However, the MainClass attribute is not being set in MANIFEST.MF. Here is my plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>net.justaprogrammer.poi.cleanser.Cleanser</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
However, this does not get added to the MANIFEST.MF in the jar generated by mvn package. The manifest generated is below:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: zippy
Build-Jdk: 1.6.0_25
What am I doing wrong?
I missed that you weren't generating your assembly on package. You have a jar project, so Maven will build a jar using the maven-jar-plugin. You don't have to have anything in your pom to tell it that. That's Maven's convention-over-configuration working for you. The jar it builds will have only your project classes and resources in it. If you want to add a Main-Class to the manifest in that jar, you should configure the jar plugin to do so. Basically, just move that archive configuration to the jar plugin.
However, if you actually want to assemble an executable fat jar--that is, a jar that includes all of your classes as well as the classes of all of your dependencies--then you have the setting in the right place, but you need to actually run the assembly plugin either using mvn assembly:single or by binding that goal to a lifecycle phase. To be clear, if you do this, then your project will output two jars: one that contains your project files and one that contains that plus the contents of all the libraries that your project depends on. The former is built by the jar plugin. That latter is built by the assembly plugin. Note that fat jars aren't commonly used, and you can run into unusual problems when you use them because they're rather outside the realm of normal Java stuff.
For copy&paste fans like me, assembled from above answer, and http://maven.apache.org/plugins/maven-assembly-plugin/usage.html#Execution:_Building_an_Assembly:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.db.search.filenet.Load</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
If you happen to be using the maven shade plugin to build a fat jar (rather than or in addition to using the assembly plugin), it's worth noting that the shade plugin handles entires in the MANIFEST.MF file a bit differently; see the shade plugin's executable jar page.
You probably need to add the maven-jar-plugin configuration too and configure the MainClass there also. The assembly unpacks all JAR files (e.g. project jar and dependency jars) and I think that the last MANIFEST.MF found in the list of JAR files "overwrites" the expected/generated manifest.mf.

Using native dependencies inside Maven

A POM dependency contains native libraries (DLLs inside a JAR file). How do I programmatically look up the path of the downloaded JAR file so I can pass it into "java.library.path"?
Answering my own question: http://web.archive.org/web/20120308042202/http://www.buildanddeploy.com/node/17
In short, you can use the maven-dependency-plugin:unpack goal to extract the libraries into a known path, and pass that into java.library.path:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.jdesktop</groupId>
<artifactId>jdic-native</artifactId>
<version>${jdic.version}</version>
<classifier>${build.type}</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
Since System.load() can't load libraries from within a jar, you will have to use a custom loader which extracts the library to a temporary file at runtime. Projects With JNI discusses this approach and provide code for the custom loader.
Library loader
We now have our JNI library on the
class path, so we need a way of
loading it. I created a separate
project which would extract JNI
libraries from the class path, then
load them. Find it at
http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.2/.
This is added as a dependency to the
pom, obviously.
To use it, call
com.wapmx.nativeutils.jniloader.NativeLoader.loadLibrary(libname).
More information is in the javadoc for
NativeLoader.
I generally prefer to wrap such things
in a try/catch block, as follows:
public class Sqrt {
static {
try {
NativeLoader.loadLibrary("sqrt");
} catch (Throwable e) {
e.printStackTrace();
System.exit(1);
}
}
/* ... class body ... */
}
An alternative would be to unpack the dependency, for example using dependency:unpack.
You can use the maven dependency plugin to copy the artifacts to a predefined path:
http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
If the DLL is inside the JAR, then you will need to copy it out to a directory before it can be loaded. (JARs that include native libraries usually do this themselves.) If your JAR isn't doing this, then you can use Class.getResourceAsStream() and write this to a directory that you've added to the java.library.path.
For an example of this, see loadNativeLibrary in JNA. It uses this technique to load it's own library (a JNI library) from a JAR.

maven-jar-plugin and transitive dependencies

I'm using both the assembly and jar plugins to deploy my application. I'm also using the jar plugin to help me generate the classpath in the manifest file using
<addClasspath>true</addClasspath>
While that seems to work, the problem comes when I try executing the jar (it has a proper main class specified) - it will fail to locate a library that's actually a transitive dependency. So my project A depends on project B, and project B depends on jar C. The assembly plugin will correctly zip up A, B, and C, but the jar plugin did not include C in the manifest, causing a ClassNotFoundException.
I don't see any options in maven-jar-plugin that lets me specify that transitive dependencies are required.
Am I doing it the right way? Anyone else managed to get transitive dependencies generated into the manifest? Maybe I'm doing something wrongly or out of order. Any help appreciated.
i tried to solve the mentioned problem. in my case it worked (maven-jar-plugin v2.2).
i've got a parent project called jarloading that has 3 childs:
main: with dependency to a
a: with dependency to b
b: with dependency to a
after calling
mvn package
publishing it using a deploy script containing
rm -r ~/Desktop/jarloading-bin
mkdir ~/Desktop/jarloading-bin
cp a/target/a-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp b/target/b-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp main/target/main-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
changing to directory
cd ~/Desktop/jarloading-bin
and running
java -jar main-0.0.1-SNAPSHOT.jar
it worked fine.
but actually the point is, how the classpath is listed in manifest file:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: rschmid
Build-Jdk: 1.6.0_07
Main-Class: Main
Class-Path: a-0.0.1-SNAPSHOT.jar b-0.0.1-SNAPSHOT.jar
pom.xml of main project:
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<mainClass>Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>a</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of a project:
...
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of b project contains nothing really special.
and attached source code and binaries:
source code
binaries
I couldn't get the maven-jar-plugin to work, I had to use the maven-assembly-plugin.
Examples:
Brian Fox's Blog (this is the one I followed)
Maven Assembly Plugin Usage Guide
similar example by Scott Leberknight
I kinda managed to resolve by... not actually resolving it. I checked closer and still don't know why some transitive dependencies aren't getting picked up - it seems to skip of them and they end up not getting generated into the MANIFEST.
I dug around a bit and played with the maven-dependency-plugin. Surprisingly, configuring <attach>true</attach> and tying it to the assembly:assembly phase solved the classpath issue.

maven javaee application client plugin

I am pretty new to maven.
Is there any plugin or packaging type suitable for building application client jar file ?
I want to add the application-client.xml file to the META-INF folder inside the jar.
The normal jar packaging doesn't include the file.
You should only need to define the project with jar packaging (and as it is the default you don't need to declare it).
If you define the application-client.xml in the src/main/resources/META-INF folder it will be included in the META-INF folder of the final jar.
To define additional information you need to configure the jar plugin as below.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.mycompany.app.App</mainClass>
<addClasspath>true</addClasspath>
</manifest>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Check out the guide to working with manifests for full details
I'm not very familiar with the JavaEE support in Maven, but it looks like the ejb plugin can generate a client jar as well if configured properly. Check this page out:
Maven EJB Plugin - Generating an EJB client