Until now开发者_JAVA百科 I found two ways to run my program with maven3:
$ mvn exec:exec -Dexec.args='...'
$ mvn assembly:assembly && java -cp all-with-dependecies.jar example.Main ...
The former uses mvn's JVM which traps exceptions and starts very slow. The later is very slow too because it has to build a big jar and to run tests.
I would something like $ mvn compile && java -cp $CLASSPATH example.Main
. Since usually CLASSPATH
is constant between runs I have to worry about it only once.
My question is how do you speed up compile in the development cycle change, compile, test?
You could try the Maven Shell. The blurb says this:
"Maven Shell is a CLI interface for Maven that enabled faster turn-around, and a more intellifent interaction with repositories and projects. Using Maven Shell, you will be able to speed up your builds because project information and Maven plugins are loaded into a single, always-ready JVM instance which can execute a Maven build."
You can build a classpath with Maven Dependency Plugin, and then reuse it:
$ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt
$ export CLASSPATH=target/classes:`cat cp.txt`
...
$ mvn compile && java -cp $CLASSPATH example.Main
Use mvn command-line less frequently, and instead use an IDE like Eclipse for quickly testing out incremental changes.
Eclipse builds incrementally i.e. it builds only changes, so is much faster.
You can skip the tests by passing the option: -Dmaven.test.skip=true
.
And why do you assume that starting a new JVM will be quicker than running the program within Maven's JVM? It's more likely to be just the opposite.
EDIT: another easy way to speed up the development cycle: use the --offline
option, except when you're changing the dependencies.
The last time I created a command line tool, I used the dependency plugin to copy all dependency jars to a directory (e.g. target/dist/lib), configured the classpath and main class in the Manifest file (Maven Jar Plugin). Then I could execute the app with:
java -jar myJar.jar
The other option besides Eclipse is to use JRebel which will effectively hot swap your code so you can keep your program running all the time.
Unfortunately JRebel is not free unless your opensource or using Scala.
If you use Eclipse (or IntelliJ) and run your program in Debug Mode you can also hot swap with your code but you can't add or delete methods.
I found these two methods to be the most productive in Java environment if you want immediate feedback.
One final option is to configure Maven to use the Eclipse compiler which is faster (supposedly) than the openjdk compiler.
If you need to implement a command line tool just take a look to the maven appassembler plugin which is very helpful in this kind of situations. In relationship with maven-assembly you can create a .tar.gz/zip archive which can be decompressed and the application can be started.
Create a single module for all your build time dependencies (annotations, embedded tomcat, code generators, etc. Build this once and attach to the compiler plugin so they are on the build path for all modules
create a small shared config and unzip it in each module at build time (check style config, logging config, etc)
place maven plugins into their own individual profiles that can be brought in just-in-time as needed. Eg check style, findbugs, JavaDoc, surefire, failsafe, code signing, etc. Your normal build should use as few plugins as possible. This really helps with troubleshooting since any plugin can be individually enabled with a -P command line option
avoid the fork config on the compiler plugin, it can double your build time. If you need -parameters then only fork once for the classes that need it.
write tests so they can run in parallel. No test should take more than a second.
use the -T 1C option to build in parallel
use the embedded version of tomcat, instead of the tomcat plugin, for launching tomcat for integration tests. Avoid starting tomcat more than once.
exclude any jars that don't need to be scanned in tomcat config properties.
structure your project into a balanced tree grouping related components under their own parent pom.
The very top is your BOM POM module, shared resource module, shared build path module. You rarely build these once you get everything organized.
Next is your top app pom that includes the following parent poms
-Common low-level modules with no dependencies.
-Gateway module that includes http client libs and interface modules.
-Biz service modules
-Containers - tomcat, Spring, DropWizzard,Etc.
-Packages - ubber jars, zips
-Runtimes - Rpms, executable jars
Poms dependencies should always point to higher level poms to avoid circular dependencies
The slower build artifacts should be last so you can work without having to wait on slow packaging.
You should be able to build any group in about 5 seconds, build your war in 5 seconds, start tomcat with spring in 10 seconds for a worst case of 20 second iteration.
the maven compiler is fast and incremental, so try to avoid generating any code that forces a recompile
create a small DSL and interpreter for your tests. We've seen this approach run twice as fast as junit.
I just took our large full build from 5 minutes to 45 seconds using these techniques. It is a lot of engineering, but worth it. This approach works with the standard maven release plugin and makes troubleshooting much easier.
Good luck. It's never fast enough
PS PCIe SSDs are a big help too
精彩评论