Maven Assembly - copy just file from sub-folder when extracting from archive - maven

I have a very specific requirement of our build infrastructure to copy some contents of another JAR dependency to a specific sub-folder of my web-application. We're using maven-assembly-plugin, and a natural way to do this is to use <dependencySet> along with <unpackOptions>.
The code sample (in assembly descriptor) I have looks as following:
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>my.group:artifact:jar</include>
</includes>
<unpackOptions>
<includes>
<include>subfolder/config.xml</include>
</includes>
</unpackOptions>
<outputDirectory>WEB-INF/otherfolder</outputDirectory>
</dependencySet>
The problem is that I can't figure out how to specify that I only want to copy just a single file artifact.jar/subfolder/config.xml to a target WEB-INF/otherfolder. The actual result is WEB-INF/otherfolder/subfolder/config.xml. As you can see, /subfolder gets appended to a final path. Is there any way to change the <include> expression so that /subfolder doesn't get appended?
Thanks in advance!

Have you ever thought about the maven-dependency-plugin which has a good support for unpacking archives.

Browsing through source reveals that this is not possible via maven-assembly plug-in. It gets all includes that are specified in assembly descriptor, and then passes this information to Plexus archiver which is used through multiple stages. Include patterns are passed to Plexus archiver as well, and then it obviously performs 'unpack' conserving directory structure.

As #khmarbaise indicates, the solution lies in combining dependency-plugin with assembly-plugin:
On package phase start by unpacking the dependencies you need to some target directory
On package (later in pom) use assembly to extract specific files from that directory into your artifact

Try this out with the <file/> tag and destName:
https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_file

Related

Maven-assembly-plugin: add multiple files of multiple directories to one output directory

Anyone an idea of how to add multiple files of multiple directories to one output directory without sub-directories using the maven assembly plugin.
Imagine following structure:
prjdir
|-dir1
|-target
|-file1
|-dir2
|-target
|-file2
...
|-dirN
|-target
|-fileN
I can use a fileSet to add the files ie.:
<fileSet>
<directory>../prjdir</directory>
<outputDirectory>myoutput</outputDirectory>
<includes>
<include>*/target/file*</include>
</includes>
</fileSet>
Which then creates the myoutput directory like:
myoutput
|-dir1
|-target
|-file1
|-dir2
|-target
|-file2
...
|-dirN
|-target
|-fileN
But what the hell I should do if I want only the files on myoutput without the directory structure of the source...
myoutput
|-file1
|-file2
...
|-fileN
This is only an simplified example, which means I need to do it a generic way.
Can't use <files><file> and also can't list every file explicitly, as they are generated dynamically without knowing the name beforehand ...
Thanks in advance for you support ...
Cheers m_n

ASCIIDOC: "Unresolved directive in...": "<stdin>" "or "index.adoc"

I am new to ASCIIDOC and just wanted to know WHERE the following problem comes from.
Setup:
Intellij with the neweset ASCIIDOC-Plugin
neweset asciidoctor-maven-plugin with preserveDirectories = true
I organized my asciidocs like this:
footer.adoc
header.adoc
index.adoc
subfolder
index.adoc
generated-docs looks like this:
footer.html
header.html
index.html
subfolder
index.html
Now, if I want the subfolder/index.html to include header & footer too, I thought I need to write include::../header.adoc[] into the adoc-file which is no problem for the Intellij-Plugin. But in the generated html you will find following error:
<p>Unresolved directive in index.adoc - include::../header.adoc[]</p>
So when I write the following into the adoc-file: include::header.adoc[] the generated html is happy but the Intellij ASCIIDOC plugin shows an error:
Unresolved directive in <stdin> - include::header.adoc[]
I am just wondering if this is a bug for the Intellij Plugin-Team or for the Maven-Plugin-Team. Or maybe someone has a workaround this problem?
And a little bonus question: Is it possible to configure the maven plugin to not generate header-/footer.htmls since they are already included into the actual htmls?
I have no experience with the maven plugin, but I do have lots of experience with AsciiDoc, the IntelliJ Plugin and the Gradle plugin.
The IntelliJ Plugin behaviour is correct. When you convert /subfolder/index.adoc, the includes are resolved relative to this file, so the include include::../header.adoc is correct.
You describe that you don't specify which file to render for the maven plugin (header.adoc is converted). This might be the problem with the maven plugin:
You just specify the source path and all documents are rendered relative to this source path and hence the /subfolder/index.adoc has the wrong source path.
With the Gradle plugin, you cann specify all documents to be converted. This would also avoid getting header.adoc converted. From the maven plugin docs I see that you can specify only a single file.
With this in mind, I would suggest to change your file structure in such a way that you have all the files to be converted in one folder. You can then specify this folder and the other files should not be converted. This also shoul dresolve your problem with the relative path name:
/src/docs/
|
+-common/
| |
| +-header.adoc
| +-footer.adoc
+-chapters/
+-main/
|
+-index1.adoc
+-index2.adoc
I know this is late, the answer is found in the documentation in the restdoc manual from Spring.io in the "Using the Snippets" section of https://spring.io/guides/gs/testing-restdocs/ There is some mention of this in the sample gradle project
The maven plugin configuration should be something like this:
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>output-html</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<sourceHighlighter>coderay</sourceHighlighter>
<backend>html</backend>
<attributes>
<toc/>
<linkcss>false</linkcss>
<snippets>
${project.build.directory}/generated-snippets
</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>

Copying java source file from different maven project and modifying its package declaration

Suppose we have two different maven projects; project A and project B
Project B uses A and needs to dynamically (using maven pluggins ?) copy a source file "A.java" from project A, modify its package declaration and compile it (project B should have the same class from project A but with other package declaration ..)
I am trying to copy the source file from A to B before modifying the package declaration and compile all.
Is this the good approach ?
So, project A expose its java file as a resource
<build>
<resources>
<resource>
<directory>src/</directory>
<includes>
<include>**/A.java</include>
</includes>
</resource>
</resources>
</build>
But how can I copy this file to B (B is a dependency in A) ? does "maven-resources-plugin" enable to copy resources from a dependency project, and if so, how do I specify the property "directory" in "resource"
I tried by specify the location of the file in the jar dependency but it did not work
Do you have other propositions ?
Thanks
Finally I solved it by the following steps:
1 - Use "maven-dependency-plugin" to extract (unpack) what I want (the source files from the jar) of included artifacts.
2 - Use "maven-antrun-plugin" to execute ant commands, to replace the strings, create the new package and move modified sources ..
see here
3 - Use "build-helper-maven-plugin" to point the compiler to the new source package in order to include them in the compilation phase
PS: These three steps must happen in the phase "generate-sources" !
maven-resources-plugin enable you to copy java source anywhere before compiling (you can initialize phases) but the problem lies in package declaration in the java file. you need to modify it also and that is not simple in maven
But why you need to do so ? why you need to use the same code in two different packages ???

suffix of the generated tar.gz in maven assembly plugin

Maven assembly plugin adds a suffix to the generated tar.gz which value is value of the <id> when there are more than one descriptor files, like here:
<descriptors>
<descriptor>src/main/assembly/bin-descriptor.xml</descriptor>
<descriptor>src/main/assembly/test-descriptor.xml</descriptor>
</descriptor>
generated files are: project-1.0.0-bin.tar.gz and project-1.0.0-test.tar.gz. When there is only one file in the descriptors, like here:
<descriptors>
<descriptor>src/main/assembly/bin-descriptor.xml</descriptor>
</descriptor>
the output is: project-1.0.0.tar.gz. How to force maven assembly to add a suffix to the name when there is only one file?
It's strange, I'm using Maven 3.0.1 and it also adds the assembly id as a prefix when I use only one descriptor. It's the default behaviour I think.
Try to force it configuring the appendAssemblyId to true.

Custom values in Maven pom.properties file

I'm trying to add custom values in the pom.properties file that Maven generates in the META-INF/maven/${groupId}/${artifactId} location
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestEntries>
<build>${BUILD_TAG}</build>
</manifestEntries>
<addMavenDescriptor>true</addMavenDescriptor>
<pomPropertiesFile>${project.build.directory}\interface.properties</pomPropertiesFile>
</archive>
</configuration>
</plugin>
The content of the interface.properties files is
# Build Properties
buildId=746
Using the documentation I have pointed the pomPropertiesFile element to an external properties, but the generated pom.properties file still has the default content after running mvn install
What's the correct usage of the pomPropertiesFile element?
EDIT
I believe that the problem lies in org.apache.maven.archiver.PomPropertiesUtil. If you look at the method sameContents in the source it returns true if the properties in the external file are the same as the defaults and false if different. If the result of sameContents is false, then the contents of the external file are ignored.
Sure enough, this has already been logged as a bug
I think you need to place a file under src/main/resources/META-INF/${groupId}/${artifactId}/interface.properties and let maven do the filtering job (configure the filtering). The file will automatically be copied to target/META-INF/maven/${groupId}/${artifactId}/ location.
See https://issues.apache.org/jira/browse/MNG-4998
Maven 3 will resolve property placeholders eagerly when reading pom.xml for all properties values that are available at this time. Modifying these properties at a later time will not affect the values that are already resolved in pom.xml.
However, if property value is not available (there's no default), then placeholder will not be replaced by the value and it can still be processed later as a placeholder. For example, if a plugin will generate some property during the build, or if placeholder is read and processed by a plugin during some build step.

Resources