Ever searched for a simple configuration, that lets you use your jetty-maven-plugin as you are used to, while working with LESS to simplify your stylesheets?
-You cannot do both, use the Client-side mode of LESS to ease development and use the lesscss-maven-plugin to automatically compile the LESS-sources into CSS for production. That does not work, because your stylesheets must be linked in different ways if you are switching between the client-side mode – which is best for development – and the pre-compiled mode – which is best for production. For the client-side mode you need something like:
-
-
- <link rel="stylesheet" type="text/css" href="styles.css" />
- <script src="less.js" type="text/javascript"></script>
-
-
- While, for the pre-compiled mode, you want to link to your stylesheets as usual, with:
-
-
- <link rel="stylesheet" type="text/css" href="styles.css" />
-
-
- While looking for a solution to this dilemma, I stumbled accross wro4j. Originally intended, to speed up page-delivery by combining and minimizing multiple resources into one through the use of a servlet-filter, this tool also comes with a maven-plugin, that let you do the same offline, while compiling your webapp.
-The idea is, to use the wro4j-maven-plugin to compile and combine your LESS-sources into CSS for production and to use the wro4j filter, to dynamically deliver the compiled CSS while developing. This way, you do not have to alter your HTML-code, when switching between development and production, because you always link to the CSS-files.
-So, lets get dirty!
-Step 1: Configure wro4j
-First, we configure wro4j, like as we want to use it to speed up our page. The details are explained and linked on wro4j’s Getting-Started-Page. In short, we just need two files: wro.xml and wro.properties.
-wro.xml
-wro.xml tells wro4j, which resources should be combined and how the result should be named. I am using the following configuration to generate all LESS-Sources beneath base/
into one CSS-file called base.css
:
-
- <groups xmlns="http://www.isdc.ro/wro">
- <group name="base">
- <css>/css/base/*.css</css>
- </group>
-
-
- wro4j looks for /css/base/*.css
inside the root of the web-context, which is equal to src/main/webapp
in a normal maven-project. There are other ways to specifie the resources, which enable you to store them elswhere. But this approach works best for our goal, because the path is understandable for both: the wro4j servlet-filter, we are configuring now for our development-environment, and the wro4j-maven-plugin, that we will configure later for build-time compilation.
wro.properties
-wro.properties in short tells wro4j, how or if it should convert the combined sources and how it should behave. I am using the following configuration to tell wro4j, that it should convert *.css
-sources into CSS and do that on every request:
-
- preProcessors=less4j
- disableCache=true
-
-
- You can do a lot more here. There are countless configuration options to fine-tune the behaviour of wro4j. The disableCache=true
is crucial, because we would not see the changes take effect when developing with jetty-maven-plugin later on. You can also do much more with your resources here, for example minimizing. But for our goal, we are now only intrested in the compilation of our LESS-sources.
Step 2: Configure the wro4j servlet-filter
-Configuring the filter in the web.xml is easy. It is explained in wro4j’s installation-insctuctions. But the trick is, that we do not want to configure that filter for the production-version of our webapp, because we want to compile the resources offline, when the webapp is build. To acchieve this, we can use the <overrideDescriptor>
-Parameter of the jetty-maven-plugin.
<overrideDescriptor>
-This parameter lets you specify additional configuration options for the web.xml of your webapp. I am using the following configuration for my jetty-maven-plugin:
-
-
- <plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <configuration>
- <webApp>
- <overrideDescriptor>${project.basedir}/src/test/resources/jetty-web.xml</overrideDescriptor>
- </webApp>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>ro.isdc.wro4j</groupId>
- <artifactId>wro4j-core</artifactId>
- <version>${wro4j.version}</version>
- </dependency>
- <dependency>
- <groupId>ro.isdc.wro4j</groupId>
- <artifactId>wro4j-extensions</artifactId>
- <version>${wro4j.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-pool</groupId>
- <artifactId>commons-pool</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.javascript</groupId>
- <artifactId>closure-compiler</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.github.lltyk</groupId>
- <artifactId>dojo-shrinksafe</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.jruby</groupId>
- <artifactId>jruby-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.jruby</groupId>
- <artifactId>jruby-stdlib</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.jruby</groupId>
- <artifactId>jruby-stdlib</artifactId>
- </exclusion>
- <exclusion>
- <groupId>me.n4u.sass</groupId>
- <artifactId>sass-gems</artifactId>
- </exclusion>
- <exclusion>
- <groupId>nz.co.edmi</groupId>
- <artifactId>bourbon-gem-jar</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.gmaven.runtime</groupId>
- <artifactId>gmaven-runtime-1.7</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>jshint</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>less</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>emberjs</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>handlebars</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>coffee-script</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>jslint</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>json2</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.webjars</groupId>
- <artifactId>jquery</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </plugin>
-
-
- The dependencies to wro4j-core and wro4j-extensions are needed by jetty, to be able to enable the filter defined below. Unfortunatly, one of the transitive dependencies of wro4j-extensions
triggers an uggly error when running the jetty-maven-plugin. Therefore, all unneeded dependencies of wro4j-extensions
are excluded, as a workaround for this error/bug.
jetty-web.xml
-And my jetty-web.xml looks like this:
-
-
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
- <filter>
- <filter-name>wro</filter-name>
- <filter-class>ro.isdc.wro.http.WroFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>wro</filter-name>
- <url-pattern>*.css</url-pattern>
- </filter-mapping>
- </web-app>
-
-
- The filter processes any URI’s that end with .css
. This way, the wro4j servlet-filter makes base.css
available under any path, because for exampl /base.css
, /css/base.css
and /foo/bar/base.css
all end with .css
.
This is all, that is needed to develop with dynamically reloadable compiled LESS-resources. Just fire up your browser and browse to /what/you/like/base.css
. (But do not forget to put some LESS-files in src/main/webapp/css/base/
first!)
Step 3: Install wro4j-maven-plugin
-All that is left over to configure now, is the build-process. If you would build and deploy your webapp now, the CSS-file base.css
would not be generated and the link to your stylesheet, that already works in our jetty-maven-plugin environment would point to a 404. Hence, we need to set up the wro4j-maven-plugin. I am using this configuration:
-
- <plugin>
- <groupId>ro.isdc.wro4j</groupId>
- <artifactId>wro4j-maven-plugin</artifactId>
- <version>${wro4j.version}</version>
- <configuration>
- <wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
- <cssDestinationFolder>${project.build.directory}/${project.build.finalName}/css/</cssDestinationFolder>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
-
- I connected the run
-goal with the package
-phase, because the statically compiled CSS-file is needed only in the final war. The ConfigurableWroManagerFactory
tells wro4j, that it should look up further configuration options in our wro.properties
-file, where we tell wro4j, that it should compile our LESS-resources. The <cssDestinationFolder>
-tag tells wro4j, where it should put the generated CSS-file. You can adjust that to suite your needs.
That’s it: now the same CSS-file, which is created on the fly by the wro4j servlet-filter when using mvn jetty:run
and, thus, enables dynamic reloading of our LESS-resources, is generated during the build-process by the wro4j-maven-plugin.
Cleanup and further considerations
-lesscss-maven-plugin
-If you already compile your LESS-resources with the lesscss-maven-plugin, you can stick with it and skip step 3. But I strongly recommend giving wro4j-maven-plugin a try, because it is a much more powerfull tool, that can speed up your final webapp even more.
-Clean up your mess
-With a configuration like the above one, your LESS-resources and wro4j-configuration-files will be packed into your production-war. That might be confusing later, because neither wro4j nor LESS is used in the final war. You can add the following to your pom.xml
to exclude these files from your war for the sake of clarity:
-
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <warSourceExcludes>
- WEB-INF/wro.*,
- less/**
- </warSourceExcludes>
- </configuration>
- </plugin>
-
-
- What’s next?
-We only scrached the surface, of what can be done with wro4j. Based on this configuration, you can easily enable additional features to fine-tune your final build for maximum speed. You really should take a look at the list of available Processors!
-
- Hi thanks a lot for making this plugin available, great work!!
-- I have a problem generating postgres schema. Looks like the plugin ignores the data type when adding default values and that yields a syntax error from Postgres. Or maybe I’m doing something wrong. I’m using version 1.0.3.
For example I have in java:
-- @Column(name = “financialEnabled”, nullable = false, columnDefinition = “default TRUE”)
-- private boolean financialEnabled; -
- Generated SQL is:
-- financialEnabled default TRUE not null, -
As you can see the data type boolean is not translated to the SQL script. Thanks a lot for your help.
---
-
-
- Kai Moritz says:
-
-
-
- November 11, 2013 at 13:09 (Edit)
-
-
-
-
-
-
-
-
-- This plugin is only a tool to automate the generation of the SQL in your development-environment.
-- Questions on how to anotate your code correctly are better asked in a user-forum from hibernate or such.
- Nevertheless, I think I can give you a usefull hint:
-- You are overwriting the automatically generated column-definition with “default TRUE”.
- Try it with
- @Column(name = âfinancialEnabledâ, nullable = false)
-- private boolean financialEnabled;
Hi,
-- looks like a very nice plugin. Unfortunately, part of our entities are in other modules/dependencies.
-- Do you plan to add the possibility to scan also for dependencies of the project or at least of the plugin?
Also, when I only want to generate the SQL and use the following configuration, I got nothing.
-Config:
-- de.juplo
-- hibernate4-maven-plugin
- 1.0.2
- true
-- SCRIPT
- NONE
- com.deutscheboerse.hibernate.PostgreSQLDialect
- ${project.build.directory}/hibernate4/cmm-schema.sql
- com.deutscheboerse.energy
-- energy-commons-hibernate
- ${commons.hibernate.version}
- org.springframework.security
-- spring-security-core
- ${spring.security.version}
- org.slf4j
-- slf4j-log4j12
- ${slf4j.version}
- Output:
-- mvn hibernate4:export -e
- [INFO] Error stacktraces are turned on.
- [INFO] Scanning for projects…
- [INFO]
- [INFO] ————————————————————————
- [INFO] Building CMM WAR 1.0.0-RC5-SNAPSHOT
- [INFO] ————————————————————————
- [INFO]
- [INFO] — hibernate4-maven-plugin:1.0.2:export (default-cli) @ cmm-war —
- [INFO] Scanning directory D:\_dev\work\ii\src\cmm\trunk\cmm-war\target\classes f
- [INFO] No hibernate-properties-file found! (Checked path: D:\_dev\work\ii\src\cm
- [INFO] Gathered hibernate-configuration (turn on debugging for details):
- [INFO] hibernate.dialect = com.deutscheboerse.hibernate.PostgreSQLDialect
- [INFO] HHH000400: Using dialect: com.deutscheboerse.hibernate.PostgreSQLDialect
- [INFO] ————————————————————————
- [INFO] BUILD SUCCESS
- [INFO] ————————————————————————
- [INFO] Total time: 10.932s
- [INFO] Finished at: Thu Oct 10 12:51:05 UTC 2013
- [INFO] Final Memory: 9M/23M
- [INFO] ————————————————————————
- Thanks for any help,
-- Milos. -
--
-
-
- Kai Moritz says:
-
-
-
- October 10, 2013 at 22:19
-
-
- (Edit)
-
-
-
-
-
-
-- Yes, I am working on the possibility, to scan for annotations in dependencies.
-- Unfortunatly, I have no example-project for this use-case by hand.
- It would help a lot, if you could provide a sample-project on github or such. -
Greetings kai
---
-
-
- Kai Moritz says:
-
-
- November 11, 2013 at 13:11 (Edit)
-
-
-
-
-
-
-Version 1.0.3 of the plugin can now scan for annotations in the dependencies, too.
- -Following my previous question, here is the debug info
-[DEBUG] Dependency: /Users/pmarques/.m2/repository/org/springframework/security/spring-security-acl/3.1.4.RELEASE/spring-security-acl-3.1.4.RELEASE.jar
- -- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/atomikos-util/3.6.5/atomikos-util-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-api/3.6.5/transactions-api-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/javax/transaction/transaction-api/1.1/transaction-api-1.1.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-jdbc-deprecated/3.6.5/transactions-jdbc-deprecated-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-jdbc/3.6.5/transactions-jdbc-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-jta/3.6.5/transactions-jta-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions/3.6.5/transactions-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/org/apache/geronimo/specs/geronimo-jta_1.0.1B_spec/1.0.1/geronimo-jta_1.0.1B_spec-1.0.1.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-jms-deprecated/3.6.5/transactions-jms-deprecated-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-jms/3.6.5/transactions-jms-3.6.5.jar
- [DEBUG] Dependency: /Users/pmarques/.m2/repository/com/atomikos/transactions-hibernate3/3.6.5/transactions-hibernate3-3.6.5.jar
- [INFO] Scanning directory /target/classes for annotated classes…
Hi,
-I have the following problem.
-- The project that I use to test (and use the plugin) has the annotated classes as a dependency.
- I am getting the error:
- No annotated classes found in directory /target/classes
Shouldn’t the plugin scan all the dependencies also?
-Thanks,
- -- Pedro.
--
-
-
- Kai Moritz says:
-
-
- August 7, 2013 at 19:12 (Edit)
-
-
-
-
-
-
-Hi Pedro,
-I think, that your observation is right.
-- But otherwise, dependencies should only be scanned if requested, because automatic scanning of the dependencies might lead to errors in other situations.
If you can make your project available to me (for example via github, or simply by mailing zipped version), I would add a configuration-parameter to enable/disable dependency-scanning and upload the refined plugin to central.
-Regards,
-Kai Moritz
- ---
-
-
- Kai Moritz says:
-
-
- October 18, 2013 at 02:52 (Edit)
-
-
-
-
-
-
-The new version 1.0.3 of the plugin adds support for annotated classes in dependencies!
- -Hello,
-I’m upgrading from hibernate3 to to hibernate4 and have moved from the hibernate3-maven-plugin to this version. I haven’t undertaken (and don’t want to just yet) the big job of changing my hbm mapping files to annotations.
-As far as I can see this is a show stopper for using your nice plugin. Can you please confirm if this is the case and whether you are planning to add support for scanning for hbm files?
-Many thanks,
-Mike Cohen.
- ---
-
-
- tortenheber says:
-
-
- July 31, 2013 at 23:18 (Edit)
-
-
-
-
-
-
-Hello Mike,
-I added the requested feature in the SNAPSHOT-version.
-- It would be nice, if you could test, if the new feature works, because I have no example project by hand, that still uses hibernate-mapping via XML.
You can download an actual build here:
-https://oss.sonatype.org/content/repositories/snapshots//de/juplo/hibernate4-maven-plugin/1.0.2-SNAPSHOT/
-or build it by yourself from the sources.
-- The feature is documented here:
http://juplo.de/hibernate4-maven-plugin-1.0.2-SNAPSHOT/export-mojo.html
-Best regards
-kai
- -Hey I have modified your code to support envers and generate auditing tables, if you want I can send you a patch. Thanks!
- ---
-
-
- admin says:
-
-
- February 22, 2013 at 19:54 (Edit)
-
-
-
-
-
-
-Your welcom.
- -- Send it!
--
-
-
- Victor says:
-
-
- February 25, 2013 at 15:28 (Edit)
-
-
-
-
-
-
-Where to? Is there a github repo?
- ---
-
-
- admin says:
-
-
- February 25, 2013 at 20:05 (Edit)
-
-
-
-
-
-
-There is a private git-Repository.
-- Check the project-documentation!
You can send me a patch or a pull-request to kai@juplo.de
- -