Can I import resources like FTL files from another Maven project in my Liferay portlet? - maven

We have several Liferay 6.2 portlets in different Maven projects. Some of these are imported as dependencies by others. While this allows me to access the java classes, I can't figure out how to import Freemarker files from one project in another project.
I assume I would need to access the resources from the dependency project, and then tell Freemarker how to find and include them. Assuming that's true, that leaves me with two questions:
How can I access resources, like FTL files and images, from another project that is list as a dependency in the Maven pom file of my Liferay project, especially in the server-side code?
How can I tell Freemarker where to look for the FTL files in the project that is listed as a dependency in the Mavan pom file?
If I'm wrong about what I need to be doing, then what is the correct way to give Freemarker access to the FTL files?
EDIT: I have a way around the first problem (though it's not a great way, I feel there's probably a better solution). I've tried to set up a Freemarker configuration using the path of the external FTL files, but I don't really know what to DO with the configuration; it doesn't look like it's actually being used.

I eventually found this question:
Maven: Extract dependency resources before test
Using the maven-dependency-plugin code in the original question and in the answer, I was able to copy the FTL files from the dependency into the Freemarker folder of the child project (in the compiled target folders of course), allowing them to be imported by Freemarker without any other changes made to the child project (the FTL files had to be moved to the resources directory in the parent project). Here are the relevant sections of the child project pom file:
I included the parent project in the dependencies:
<dependency>
<groupId>ourGroupId</groupId>
<artifactId>parentArtifactId</artifactId>
<version>1.0.0</version>
</dependency>
And then added the maven-dependency-plugin in the plugins section of the build, using the same artifact id I used in the dependency section:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>resource-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>parentArtifactId</includeArtifactIds>
<includes>freemarker/*/*.ftl</includes>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
I chose the phase and goals that seemed to make sense, I'm not sure if they're "optimal" but they seem to work. The FTL files are inside a sub-folder, under the "freemarker" folder, in the resources directory of the parent file. The "includes" parameter is a bit more restrictive that I thought, it seems I need to have the correct folder depth specified in order to import the files correctly, but that's fine.
Just for clarity, I made sure the resulting location of the copied Freemarker files matched the Freemarker that folder had already been specified in the applicationContext.xml file:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
</bean>

Related

how to make zip files (produced by a self-made maven plugin)from target folder end up in the local repository?

I am creating my own maven-environment-plugin that creates and bundle resources for a predefined folder structure for each environment defined in the configuration. The plugin is outputting the folder structure and resource in a zip file and placing it in the target folder.
Questions:
How can I make my plugin work like the maven-assembly-plugin so my output to target folder also ends up in my local repository when I use 'mvn install'?
Do I need to mark it or something? Its automaticallly doing it when the maven-assembly-plugin is used.
How does maven-assembly-plugin manage to make sure of this?
I am using mojo for my plugin development.
<plugin>
<groupId>dk.kmd.devops.maven.plugin</groupId>
<artifactId>envconfiguration-maven-plugin</artifactId>
<version>1.0.3</version>
<configuration>
<environments>
<environment>${env.local}</environment>
<environment>${env.dev}</environment>
<environment>${env.t1}</environment>
<environment>${env.t2}</environment>
<environment>${env.p0}</environment>
</environments>
<sourceConfigDir>${basedir}/src/main/config</sourceConfigDir>
<zipEnvironments>true</zipEnvironments>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generateEnv</goal>
</goals>
</execution>
</executions>
</plugin>
You need to attach (that's the correct terminology in this case) the new artifact (the generated zip file) to the build as part of its official artifacts.
This is basically what the attach-artifact goal of the build-helper-maven-plugin does:
Attach additional artifacts to be installed and deployed.
From its official examples, the attach goal:
Typically run after antrun:run, or another plugin, that produces files that you want to attach to the project for install and deploy.
The another plugin in this case can be the plugin you developed. Hence there are two solutions to your case:
Configure this plugin to attach the generated artifact as a further pom.xml configuration, or
add to your plugin the functionality to automatically attach the generated file
The second case can be covered via Maven API, using the MavenProjectHelper and its attachArtifact method.
In your mojo, you can import is as a component via:
/**
* Maven ProjectHelper
*/
#Component
private MavenProjectHelper projectHelper;
Then use the aforementioned method:
projectHelper.attachArtifact(project, "zip", outputFile);
You should probably already have the required Maven dependency providing it, but just in case it would be this one:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>
Note that the artifact will be attached to the build as an additional artifact via a classifier, that is, a suffix to the default artifact name differentiating it from the default artifact and making it unique as output of the build.
As a reference to real example and to further answer your (last) question, check this query on the GitHub maven-plugins repository, checking for the attachArtifact string, you will see it used in a number of Maven plugins, among which the maven-assembly-plugin, for example here in the AbstractAssemblyMojo class.

Extract current folder name within maven pom.xml file

I am looking for a way to dynamically extract the current folder name within maven pom.xml file.
For Example:
if the pom.xml file is at /home/jenkins/workspace/bdms-ci/bdms-bcr/pom.xml
then bdms-bcr is the current folder.
See a code snippet:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<testClassesDirectory>../../bdms-ci-improve/${project.basedir}/target/test-classes</testClassesDirectory>
<classesDirectory>../../bdms-ci-improve/${project.basedir}/target/classes</classesDirectory>
</configuration>
</plugin>
${project.basedir} will bring the full path which is not good since only the current folder is needed.
I tried to work with MavenProject class from the maven api document:
${project.file.parentFile.name} or ${project.file.name}, but it didn't work.
remember it is maven multi project and everything has to be dynamically.
The whole issue is for jenkins ci build which use parallel-test-executor plugin. I would like to compile once in the main job and then all the other test execute jobs will will only test by looking into the compiled code.
Using maven 3.2.3
#guymi,
Seems like you should be able to simply use ${project.artifactId} or perhaps ${parent.artifactId}.
EDIT
Or does your artifactId name disagree with the directory it's stored in?
If so, that's possible but not good practice and should be avoided.
It is not possible to do it. simple as that.
A workaround solution is by using artifactId with the same name as folder name. then you can do:
../../bdms-ci-improve/${project.artifactId}/target/test-classes</testClassesDirectory>

Intellij: jboss-ejb3.xml entry keeps disappearing from ${PROJECT_DIR}/.idea/artifacts/XXX_war_exploded.xml

Why is it that although I've
set the proper path to the JBoss EJB deployment descriptor in my project's EJB facet
added jboss-ejb3.xml to Intellij's artifact Patrac-web:war exploded's <output root>/WEB-INF
that any time I make the simplest change to pom.xml Intellij removes the following entry from ${PROJECT_DIR}/.idea/artifacts/Patrac_web_war_exploded.xml:
<element id="file-copy" path="$PROJECT_DIR$/Patrac-ejb/src/main/resources/META-INF/jboss-ejb3.xml" />
and, as a result, jboss-ejb3.xml does not get copied to the target directory?
It's as though each time I make a change to pom.xml Intellij "reloads" the deployment configuration using the POM to override what settings I make within the IDE. Perhaps because I have no entry in my pom.xml for copying jboss-ejb3.xml from source directory to target directory the settings I make in Intellij IDE keep disappearing whenever Intellij "reloads." Pure conjecture on my part, but this is what seems to be happening.
If so, what change do I need to make to pom.xml in order to make this stop happening?
When a project is (re)imported from Maven IDEA configures it such way that when you invoke 'Build' from IDEA it produces the same result as Maven's 'package' goal. If you need to copy jboss-ejb3.xml to WEB-INF just put it under 'src/main/webapp/WEB-INF' directory and it will be copied by Maven and so do IDEA.
Here is an alternative to Nik's solution that I tried because I wanted to leave jboss-ejb3.xml in META-INF. Taking a look at the maven documentation, which shows how to treat jboss-ejb3.xml as a web resource and copy it into WEB-INF, I added the following to the maven-war-plugin configuration and the problem was resolved. Well, kinda sorta. But not really.
<webResources>
<resource>
<directory>../Patrac-ejb/src/main/resources/META-INF</directory>
<includes>
<include>jboss-ejb3.xml</include>
</includes>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
Although doing it this way eliminated the need to fiddle around with IDEA facet configuration settings (because Maven was configured to copy the file, not IDEA), a new problem was introduced: two copies of jboss-ejb3.xml appeared in the WAR, one in WEB-INF and the other inside the EJB JAR (in META-INF). Although there were no apparent consequences (the application ran just fine) I preferred not to have a duplicate copy of the descriptor located inside the EJB JAR.
Using the Maven EJB plugin documentation, I tried to add an exclusion to my maven-ejb-plugin configuration e.g.
<configuration>
<ejbVersion>3.1</ejbVersion>
<excludes>
<exclude>**/jboss-ejb3.xml</exclude>
</excludes>
</configuration>
This should have prevented the duplicate copy of jboss-ejb3.xml from appearing in the EJB JAR META-INF but it didn't work for me, and after fruitlessly googling various variations of "maven-ejb-plugin excludes not working properly" I gave up.
If I could have gotten the excludes to work then I would have preferred this solution over moving jboss-ejb3.xml into src/main/webapp/WEB-INF because although this solution is slightly more complex (it requires additional Maven configuration settings in two POMs), the EJB-related descriptor would remain in the EJB module.
I've decided to go with Nik's solution until I can resolve the excludes problem.

Maven: Force Jersey to use specific artifact version

I have a Maven repository where I load Jena TDB 0.9.3 (which depends on Jena ARQ 2.9.3), Jersey 1.8 and RMOnto 1.0. The point is, as you expected, to do some analysis on semantic datasets.
It looks like RMOnto has ARQ 2.8.7 built in, as in "hardwired". There isn't any explicit dependency in its pom file, yet the jar file contains a ARQ.class. It's very tricky because you won't notice it with Maven Enforcer Plugin and the like.
It looks like this causes Jersey to use RMOnto's ARQ version instead of the one defined in pom.xml. Here is a minimal example. When you run the test (checks whether or not ARQ.VERSION equals 2.9.3), it succeeds. When you build the project and deploy it on a Tomcat 7, you should see 2.8.7 as output.
Is this behaviour expected and why?
How could one force Jersey to use ARQ 2.9.3?
In case it's not possible, could one isolate RMOnto to use 2.8.7 while the rest of the source uses 2.9.3?
Thanks in advance!
You should define the ARQ 2.9.3 first in the dependencies list. By doing that you force your build to use that specific version. The dependency order is relevant when choosing what artifact to use.
Update
OK, I understand what the problem is.
The RMOnto jar is obviously shaded according to the pom: http://semantic.cs.put.poznan.pl/maven/put/semantic/RMOnto/1.0/RMOnto-1.0.pom.
Tomcat 7 loads the jars in WEB-INF/lib in an undefined order. This means that even if you define ARQ 2.9.3 to be first in your dependencies it will not be the case when the application is run in Tomcat. http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
Good thing is that Tomcat always look in WEB-INF/classes before WEB-INF/lib for dependencies.
So what you can do as a work around is to make sure that the ARQ 2.9.3 version is added to the WEB-INF/classes folder. This can be done using the maven-dependency-plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
<version>2.9.3</version>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<excludes>**/META-INF/</excludes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Your war as well as your exploded war will now contain all the classes from ARQ 2.9.3 in the WEB-INF/classes folder. They will be loaded before any jar-file that is in WEB-INF/lib folder.
NB: I have not tested this on Tomcat but I cannot see that it would not work.
NB2: This is a hack. Best thing would be to remove the ARQ packages out of the RMOnto jar.
You should file a defect report against RMOnto. Hard-wiring library code into a jar, instead of including it as a dependency you can manage in the POM, is definitely a bad idea that the code maintainer should fix.
If the files have been copied directly to the RMOnto .jar, the behaviour is expected.
In that case, I'd say the best bet is to hardcode it away, aka remove the ARQ files directly from the package. Opening up the RMOnto-1.0.jar package one can see arq files in the arq folder. What you'd need to do is open up the jar file (it's just a .zip), remove the ARQ files from there, store the edited RMOnto package in your version control / repository and refer to the edited package from there. Also, you'd need to add excludes statement to your pom for the old version of ARC and keep the dependency to the new version.
If you feel like it, it would be also good practice to remove the other dependencies that haven't been mentioned in the RMOnto's pom file, then add them in the RMOnto pom file (and rebuild, if you have the source code). This way Maven mechanism would be aware of them. The file seems to contain a lot of dependencies like this, which will cause headaches in the future.

Where should a custom Netbeans Platform conf. file be so that maven finds it?

Applications built on top of the NetBeans platform have a <myappdir>/etc/<myapp>.conf file determining, among other things, application JVM parameters. Historically, this file was a part of the NetBeans IDE installation (as far as I could tell), but starting with NB 6.9, custom files are now supported.
I am having trouble packaging a custom configuration file using Maven to build the application.
I imagine the app.conf property should have been set in the project's pom under project/build/pluginManagement/plugins like so:
<plugin>
...
<configuration>
<brandingToken>${brandingToken}</brandingToken>
<cluster>${brandingToken}</cluster>
<appConf>myapp.conf</appConf>
</configuration>
The maven module representing my application contained no prior source, so I created the src/main/nbm folder and placed myapp.conf in src/main/nbm. This isn't picked up by nbm-maven-plugin. and putting the conf file into src/main/resources doesn't make a difference.
So, can anyone explain how a NetBeans Platform application with a custom configuration file can be built using maven?
UPDATE:
With Tim's prod in the right direction, I found the answer documented on Geertjan's blog. The solution is to configure the nbm-maven-plugin like so in the application module pom:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>nbm-maven-plugin</artifactId>
<configuration>
<etcConfFile>src/main/resources/my.conf</etcConfFile>
</configuration>
</plugin>
</plugins>
</build>
BTW, if you need a second name with Geertjan, you're not really a NetBeans platform developer. ;)
Have a look at the documentation of the nbm:cluster-app plugin, specifically the part on the conf file.
As per my understanding that should allow you to replace the default one with a custom one that you create.

Resources