Google App Engine - parameters in pom.xml not read in appengine-web.xml - maven

Dear Stackoverflow community,
what I'd like to do:
working with Eclipse, use GoogleAppEngine in combination with Google CloudSQL to connect to a database and print out results
which tutorial am I following:
It's the "using Cloud SQL for MySQL" tutorial right here:
https://cloud.google.com/appengine/docs/standard/java/cloud-sql/using-cloud-sql-mysql
what have I achieved so far:
I can make it work and print out values from my database when I hardcode user, pass and database into appengine-web.xml:
<system-properties>
<property name="cloudsql" value="jdbc:google:mysql://XXXYYYZZZ:europe-west3:XXXYYYZZZ/Database?user=root&password=12345" />
</system-properties>
and then, in HelloAppEngine.java, get this url with System.getProperty("cloudsql"):
final String selectSql = "SELECT favID from favs";
PrintWriter out = resp.getWriter();
resp.setContentType("text/plain");
String url = System.getProperty("cloudsql");
try (
Connection conn = DriverManager.getConnection(url);
ResultSet rs = conn.prepareStatement(selectSql).executeQuery()) {
out.print("Last 10 visitsss:\n");
while (rs.next()) {
out.println(rs.getString("favID"));
}
} catch (SQLException e) {
out.println("fehlerddddd: " + e);
out.println(System.getProperty("cloudsql"));
}
What I dont understand though:
According to the tutorial, I dont have to hardcode user, pass and database values in the appengine-web.xml, but rather have them in a pom.xml file and then "fetch" those values from there by using ${INSTANCE_CONNECTION_NAME}, /${database}, user=${user} and password=${password}.
My pom.xml file contains these information:
<properties>
<appengine.maven.plugin.version>1.3.2</appengine.maven.plugin.version>
<appengine.api.sdk.version>1.9.62</appengine.api.sdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
<INSTANCE_CONNECTION_NAME>XXXYYYZZZ:europe-west3:faverdb</INSTANCE_CONNECTION_NAME>
<user>root</user>
<password>12345</password>
<database>XXYYZZ</database>
and also:
<dependency> <!-- Only used locally -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version> <!-- v5.x.x is for production, v6.x.x EAP X DevAPI -->
</dependency>
<dependency>
<groupId>com.google.cloud.sql</groupId>
<!-- If using MySQL 6.x driver, use mysql-socket-factory-connector-j-6 instead -->
<artifactId>mysql-socket-factory</artifactId>
<version>1.0.5</version>
</dependency>
So, the final question:
What am I missing that using ${placeholder} in my appengine-web.xml does not work while hardcoding the necessary information in there right away does work?
I'd appreciate any help :)

Ok, I found the solution:
When you add a new Google App Engine standard app, the pom file contains the following part:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>display-dependency-updates</goal>
<goal>display-plugin-updates</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.maven.plugin.version}</version>
</plugin>
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.9.62</version>
</plugin>
</plugins>
Eclipse shows a warning: "This app engine mavin plugin has been deprecated" which made me suspicious.
Looking at the complete pom.xml file linked by google:
https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine-java8/cloudsql/pom.xml
I saw that their plugin section looks different:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<deploy.promote>true</deploy.promote>
<deploy.stopPreviousVersion>true</deploy.stopPreviousVersion>
</configuration>
</plugin>
I did not look at this part since its not explicitely mentioned on the tutorials main page:
https://cloud.google.com/appengine/docs/standard/java/cloud-sql/using-cloud-sql-mysql
Replacing my plugin section with this plugin section did the trick. I guess the part where
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
is placed is responsible. So, problem solved :)

Related

Which dependencies do I have to include in a Maven Apache Storm Project?

I am pretty new to Apache Storm and Maven projects, so I tried to follow this "tutorial" (which from my point of view is not a tutorial at all):
http://storm.apache.org/releases/current/Creating-a-new-Storm-project.html
There is a huge pom.xml referenced (https://github.com/apache/storm/blob/v1.1.1/examples/storm-starter/pom.xml) which shall be used as basis for a new project. I tried to figure out what to copy into my project pom.xml. So I decided to start with the apache core dependency first. My pom.xml looks like this:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>StormTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>false</includePluginDependencies>
<classpathScope>compile</classpathScope>
<mainClass>${storm.topology}</mainClass>
<cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>StormTest-1.0-SNAPSHOT_dep</finalName>
<archive>
<manifest>
<mainClass>de.arphi.bi.WordCountTopology</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/resources</directory>
<filtering>false</filtering>
<includes>
<include>log4j2.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
This even works when it is about runing maven and building / packaging a jar. The outcome are two jar files (a small one without dependencies and a bigger one with dependencies). I cannot run the smaller one because it says "main manifest not found". But I can run the bigger one by executing the following command:
storm -jar StormTest-1.0-SNAPSHOT_dep.jar
Actually the runs on my locally installed apache storm 1.1.1 (I have some System.out.printlns ...) but I get an exception:
2018-01-02 21:38:31,864 main ERROR Unable to create file C:\Users\Artur\Desktop\Bi\apache-storm-1.1.1\logs/access-web-${sys:daemon.name}.log java.io.IOException: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch
at java.io.WinNTFileSystem.canonicalizeWithPrefix0(Native Method)
at java.io.WinNTFileSystem.canonicalizeWithPrefix(WinNTFileSystem.java:451)
at java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:422)
at java.io.File.getCanonicalPath(File.java:618)
at java.io.File.getCanonicalFile(File.java:643)
at org.apache.logging.log4j.core.util.FileUtils.makeParentDirs(FileUtils.java:134)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:573)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:554)
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:155)
at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:131) at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:60)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:952)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:892)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:884)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:508) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:232)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:244)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at org.apache.storm.topology.BasicBoltExecutor.<clinit>(BasicBoltExecutor.java:28)
at org.apache.storm.topology.TopologyBuilder.setBolt(TopologyBuilder.java:215)
at de.arphi.bi.WordCountTopology.main(WordCountTopology.java:22)
It says something about the syntax for creating a directory is wrong. And I know that it is about logging. I played arroung with different other dependencies (log4j, slf4j) and tried ecen to exclude dependecies without any success. I cannot get rid of this error.
Any ideas? I think that I am missing a dependency or that I have to exclude some parts of my pom.xml. But since I am not an Maven expert it is really hard for me to figure out what I have to adapt here.
I agree that storm-starter has gotten pretty big, and we should maybe have more of a minimal example.
First you should set the storm-core dependency to "provided" scope. When you deploy the topology to Storm, your jar will use the storm-core jar present in the Storm installation, so you shouldn't also put it in your fat jar.
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
When your topology runs on Storm, it will use the Log4j2 configuration in the log4j2/worker.xml file in your Storm installation. You shouldn't include your own log4j2.xml. If you need to set specific log levels, you can either modify worker.xml or use the CLI as described at http://storm.apache.org/releases/1.1.1/dynamic-log-level-settings.html.
Other than that your pom looks fine. I don't know why you have exec-maven-plugin in there (Edit: I see it's also in storm-starter, I think it's a leftover from when it was possible to run storm-starter in local mode. You shouldn't need it), and I might replace maven-assembly-plugin with the shade plugin, but I'd expect your topology to work regardless.
Thank Stig Rohde Døssing. Finally I found the origin for my exception base on your hint regarding the log4j2/worker.xml. The issue was not in the worker.xml, but in the cluster.xml which is located in the same directory.
When reading my Exception shown here, you can see that Java complains about creating a system path ("access-web-${sys:daemon.name}.log"). I found the placeholder sys:daemon.name in the cluster.xml and replaced it with something static like "access-web-mysysdaemonname.log". That fixed the issue. I have no idea why this placeholder could not be resolved by the system while there was no trouble with other placeholders.
Thanks for the hints. Topic can be closed.

Jersey fails when creating uber jar with maven-assembly-plugin

I have created a maven jersey starter webapp. Also I have embedded jetty server in my app using jetty plugin.
My project is working fine when I run my project using mvn jetty:run command.
But when I package my project using mvn clean package command and run the jar file which has name jar-with-dependencies the project throws this exception while returning a json response from a jersey resource.
SEVERE: MessageBodyWriter not found for media type=application/json, type=class com.nitish.freecharge.model.Count, genericType=class com.nitish.freecharge.model.Count.
Here is my pom.xml file
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nitish.freecharge</groupId>
<artifactId>wordcount</artifactId>
<packaging>war</packaging>
<version>2.0</version>
<name>wordcount</name>
<build>
<finalName>wordcount</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/webapp</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.0.v20150612</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>/wordcount</contextPath>
</webApp>
<httpConnector>
<!--host>localhost</host -->
<port>9999</port>
</httpConnector>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>package-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<finalName>awesomeProject</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.8.v20160314</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.3.8.v20160314</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.2</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
I have created my Main Driver class as App.java in default package. Here is my App.java content
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class App {
public static void main(String []gg){
Server server = new Server(9999);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
context.setContextPath("/");
server.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/wordcount/*");
jerseyServlet.setInitOrder(1);
jerseyServlet.setInitParameter("jersey.config.server.provider.packages","com.nitish.freecharge.resources");
try {
System.out.println("Starting the server..");
server.start();
System.out.println("Server started");
server.join();
} catch(Exception e) {
System.out.println("Exception in starting the server ");
e.printStackTrace();
}
}
}
Here is my only jersey resource class which gets executed when I access my project url after starting the server :
package com.nitish.freecharge.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.nitish.freecharge.dao.FileDAO;
import com.nitish.freecharge.model.Count;
/**
* Root resource (exposed at "count" path) which handles HTTP GET method and returns the count value;
*/
#Path("/count")
public class CountResource {
private FileDAO fileDAO=new FileDAO();
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "application/json" media type.
*
* #return String that will be returned as a application/json response.
*/
#GET
#Produces(MediaType.APPLICATION_JSON)
#QueryParam("query")
public Response getWordCount(#QueryParam("query")String query) {
Error error=null;
Count count=null;
try{
if(query!=null){
query=query.trim();
if(query.length()>0 && query.matches("^[A-Za-z]+$")){
long c=fileDAO.getCount(query.toLowerCase());
count=new Count(c);
}else{
error=new Error("Some Error Occured.Please Try Again With a new word!");
}
}else{
error=new Error("Some Error Occured.Please Try Again!");
}
}catch(Exception e){
error=new Error(e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
if(count!=null){
return Response.status(Status.OK).entity(count).build();
}else{
return Response.status(Status.BAD_REQUEST).entity(error).build();
}
}
}
After packaging and run the complete embedded project using command
java -jar awesomeProject.jar
I get this output on the server prompt
I have tried a lot and unable to package my embedded webapp in such a way that this issue gets resolved. I am new to maven and packaging. Kindly Help where I am committing mistake.
If you look inside the MOXy jar, you will see a folder META-INF/services. In that folder, you will see a file named org.glassfish.jersey.internal.spi.AutoDiscoverable. The content of that file should be a single line
org.glassfish.jersey.moxy.json.internal.MoxyJsonAutoDiscoverable
What this file is for is to allow Jersey to discover the MoxyJsonAutoDiscoverable, which registers MOXy for Jersey. This service loader pattern allows Jersey to discover features and register them, without us having to register them ourselves.
The problem this poses when creating an uber jar is that there may be multiple jars with the same file, as different jars have different features to discover, but the file needs to be that exact name as that is how the service loader pattern works.
So you have a bunch of jars with the same file, but when you create the uber jar, you cannot have multiple files with the same name. It's just not possible. So only one of the files gets put into the final jar. Which one.. who knows. But that means that if MOXy's files is not that one file then its feature will not be auto-discovered, and we need to register it ourselves. So the classes are packaged in the uber jar, but the main feature component is just not registered. You could just register it yourself
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
"org.glassfish.jersey.moxy.json.MoxyJsonFeature");
but what about all the other possible features that are possibly left out because their auto-discoverable file is not included?
For this reason, instead of the assembly plugin, you should use the maven-shade-plugin, which has transformers that allow us to concatenate the contents of service files into one file.
The configuration would look something like
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.YourApp</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
The ServicesResorceTransformaer is what concatenates the files. This particular configuration of the plugin was taking from the Dropwizard getting started. You may want to check that out for further explanation.

Javascript and CSS files combining in Maven build WITHOUT compression, minification etc

Is there an Maven plugin that just combines js and css resources but doesn't do any minification, obsucation, compressing etc? Just simple resources concatenation.
Make the following changes to your project:
In your pom.xml, <dependencies> tag, place:
<!-- JAVASCRIPT COMBINATION -->
<dependency>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-core</artifactId>
</dependency>
In your pom.xml, <plugins> tag, place:
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<targetGroups>allDev</targetGroups>
<destinationFolder>${basedir}/src/main/webapp/</destinationFolder>
<contextFolder>${basedir}/src/main/webapp/</contextFolder>
</configuration>
</plugin>
In your pom.xml (or the parent pom.xml) <dependencyManagement> tag, place:
<!-- JAVASCRIPT COMBINATION -->
<dependency>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-core</artifactId>
<version>1.8.0</version>
</dependency>
Create a wro.xml under /project/src/main/webapp/WEB-INF and place something like the following:
<?xml version="1.0" encoding="UTF-8"?>
<groups xmlns="http://www.isdc.ro/wro">
<group name="allDev">
<js minimize="false">/my1stJsFolder/*.js</js>
<js minimize="false">/my2ndJsFolder/*.js</js>
<js minimize="false">/someFileDirectlyUnderWEBINF.js</js>
</group>
</groups>
In web.xml insert:
<filter>
<filter-name>WebResourceOptimizer</filter-name>
<filter-class>ro.isdc.wro.http.WroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>WebResourceOptimizer</filter-name>
<url-pattern>/wro/*</url-pattern>
</filter-mapping>
allDev.js will be generated under /project/src/main/webapp.
I am not sure yet how I could tell wro4j to only generate one in target (now you have two - one in the project source files and one in target).
When compressing with yui plugin I only get one in target. But this should not be that big of a problem for you.
For more:
https://code.google.com/p/wro4j/wiki/GettingStarted
https://code.google.com/p/wro4j/wiki/MavenPlugin
http://www.jarvana.com/jarvana/search?search_type=project&project=wro4j-maven-plugin
ADDITIONALLY:
If you have any problems with the resource processing try adding to <build> tag:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
And also to <plugins> add
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>swf</nonFilteredFileExtension>
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
<nonFilteredFileExtension>jpeg</nonFilteredFileExtension>
<nonFilteredFileExtension>class</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
<nonFilteredFileExtension>exe</nonFilteredFileExtension>
<nonFilteredFileExtension>wmv</nonFilteredFileExtension>
<nonFilteredFileExtension>jar</nonFilteredFileExtension>
<nonFilteredFileExtension>zip</nonFilteredFileExtension>
<nonFilteredFileExtension>gz</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
I think most tools will allow you to turn off the minification.
Here is another couple that look interesting:
http://jawr.java.net/
https://code.google.com/p/wro4j/
Looks about right :
http://hammerfest.sourceforge.net/maven-javascript-plugin/merge-mojo.html
I've used YUI Compressor for years. Used to do it in ANT, but there is also a maven plugin as well. The following link is an example for aggregation:
http://alchim.sourceforge.net/yuicompressor-maven-plugin/ex_aggregation.html

docbkx-maven-plugin: No output during run of plugin

I set up the docbkx-maven-plugin to generate PDF documentation for a source project. In the parent pom I specified the version to be used as well as the reference to the docbook version to use:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
<version>2.0.14</version>
<dependencies>
<dependency>
<groupId>net.sf.docbook</groupId>
<artifactId>docbook-xml</artifactId>
<version>5.0-all</version>
<type>zip</type>
<classifier>resources</classifier>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</pluginManagement>
In the actual project I use the configuration:
<build>
<plugins>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
<executions>
<execution>
<id>usersmanual</id>
<phase>generate-resources</phase>
<goals>
<goal>generate-pdf</goal>
</goals>
<configuration>
<includes>${basedir}/UserManual/*.xml</includes>
<includes>${basedir}/UserManual/src/*.xml</includes>
<targetDirectory>${project.build.directory}/UserManual</targetDirectory>
<chunkedOutput>true</chunkedOutput>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
No matter what goal(s) I specify or what includes I provide, the plugin performs no(!) operation. There is no target directory created and I do not see any meaningful output on the command line. The result looks like:
[INFO] --- docbkx-maven-plugin:2.0.14:generate-pdf (usersmanual) # documentation ---
[INFO]
I use Maven 3.0.3.
What do I miss here? Is there any configuration not provided, yet, which will start the plugin to do some work?
UPDATE:
This is what I have now:
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
<version>2.0.14</version>
<dependencies>
<dependency>
<groupId>net.sf.docbook</groupId>
<artifactId>docbook-xml</artifactId>
<version>5.0-all</version>
<type>zip</type>
<classifier>resources</classifier>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>generate-pdf</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<sourceDirectory>${project.basedir}/UserManual</sourceDirectory>
<xincludeSupported>true</xincludeSupported>
<includes>${project.basedir}/UserManual/UserManual.xml</includes>
<includes>${project.basedir}/UserManual/**/*.xml</includes>
<targetDirectory>${project.build.directory}/UserManual</targetDirectory>
</configuration>
</execution>
</executions>
</plugin>
At least the directory target/Usermanual is greated, but it is still empty. Why is there still not output? Do I have a chance to get a meaningful log file from docbkx? mvn ... -X does not tell much.
Your latest example contains two includes configuration options which is not valid maven configuration.
My recommendation is to stop trying to override all these defaults and accept the default location for the docbook source xml, at least initially while you get comfortable with the plugin and can diagnose what issues are from what changes.
Anyway, your <includes> should be just the root xml file of the documentation you're trying to generate as it exists in the <sourceDirectory>. You do not need to include all of the xml files, you instead need to follow the xincludes approach since you're declaring its usage. There are a number of projects using this mechanism that you can review and copy the usage of.
Ours is: https://github.com/jetty-project/jetty-documentation
We have a bit more complex usage since we use the maven filtering plugin to avoid having to mess with entities and the like. Getting back to your includes usage, if your top level docbook file is index.xml then your includes would simply be:
<includes>index.xml</includes>
No expressions or globs needed, you bring in the other xml documents with the <xi:include> tags where needed.

Generating Multiple TLDs With Maven Javadoc Plugin & TLDGen

I've got a taglib project that I use the TLDGen library to help build my TLD files from annotations in my classes. I've then got it plugged into the Maven JavaDoc plugin to have it build the TLD files via the javadoc:javadoc Maven goal. Pom portion that handles this is as follows:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<doclet>org.tldgen.TldDoclet</doclet>
<docletArtifact>
<groupId>com.google.code.tldgen</groupId>
<artifactId>tldgen-all</artifactId>
<version>1.0.0</version>
</docletArtifact>
<show>private</show>
<additionalparam>-name test
-uri "http://www.mycompany.com/tags/wibble"
-tldFile ..\..\..\src\main\resources\META-INF\w.tld
</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
<author>false</author>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
And this works fantastically. Trouble is that I know want to create 2 TLD's from this project. I can pass a -subpackages attribute in th addtionalparam element so I can produce a TLD with exactly what I want.
But I can only have one configuration element at that point. I've tried moving the configuration into the reporting section in my pom with two reportsets to see if that helps but no luck.
Has anyone ever attempted this before and can help point me in the right direction for getting it right? Cheers!
It's been a while since this question was posted, but here's how I did multiple tld generation with TLDGen. I started from your question, since the guys over at the project used your answer as a reference :).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<includes>
<include>**</include>
</includes>
<doclet>org.tldgen.TldDoclet</doclet>
<docletArtifacts>
<!-- listing all dependencies for tldgen:
the tldgen library, commons-logging, commons-io,
commons-lang, geronimo-jsp_2.1_spec, log4j, saxon, stax
not sure if they have to be listed here, will have to check; if I
don't set them I get class not found errors, but I'm guessing I
have a misconfiguration -->
</docletArtifacts>
<show>private</show>
<additionalparam>
-htmlFolder ${basedir}/target/docs
-tldFolder ${basedir}/src/main/java/META-INF
-license NONE
</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
<author>false</author>
<encoding>utf-8</encoding>
</configuration>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jsr173_api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>

Resources