Skip to content

Commit

Permalink
Back to using runtime scope for (super)devmode, but make it configura…
Browse files Browse the repository at this point in the history
…ble.

Using different scopes for compiler vs. devmode makes it possible to have
slightly different dependencies in those cases. In most cases, dependencies
are expected to be in the compile scope so the classpaths would be
identical between compiler and devmode.
For "legacy" projects that mix client and server code in the same Maven
module, making it configurable allows for having GWT dependencies in the
provided scope. This will help in migrating those projects to this plugin
one step at a time.
  • Loading branch information
tbroyer committed Nov 15, 2015
1 parent 1d9d1c6 commit 69ac0f3
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
37 changes: 29 additions & 8 deletions src/main/java/net/ltgt/gwt/maven/AbstractDevModeMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
Expand Down Expand Up @@ -53,6 +52,20 @@ public abstract class AbstractDevModeMojo extends AbstractMojo {
@Parameter(property = "gwt.projects")
protected String projects;

/**
* The dependency scope to use for the classpath.
* <p>The scope should be one of the scopes defined by org.apache.maven.artifact.Artifact. This includes the following:
* <ul>
* <li><i>compile</i> - system, provided, compile
* <li><i>runtime</i> - compile, runtime
* <li><i>compile+runtime</i> - system, provided, compile, runtime
* <li><i>runtime+system</i> - system, compile, runtime
* <li><i>test</i> - system, provided, compile, runtime, test
* </ul>
*/
@Parameter(defaultValue = Artifact.SCOPE_RUNTIME)
protected String classpathScope;

/**
* Specifies Java source level.
*/
Expand Down Expand Up @@ -177,12 +190,18 @@ public void execute() throws MojoExecutionException, MojoFailureException {
if (prependSourcesToClasspath()) {
cp.addAll(sources);
}
try {
for (MavenProject p : projectList) {
cp.addAll(p.getCompileClasspathElements());
for (MavenProject p : projectList) {
ScopeArtifactFilter artifactFilter = new ScopeArtifactFilter(classpathScope);
cp.add(p.getBuild().getOutputDirectory());
for (Artifact artifact : p.getArtifacts()) {
if (!artifact.getArtifactHandler().isAddedToClasspath()) {
continue;
}
if (!artifactFilter.include(artifact)) {
continue;
}
cp.add(artifact.getFile().getPath());
}
} catch (DependencyResolutionRequiredException e) {
throw new MojoExecutionException(e.getMessage(), e);
}

try {
Expand Down Expand Up @@ -239,15 +258,17 @@ protected boolean prependSourcesToClasspath() {

protected abstract void forceMkdirs() throws IOException;

private final ScopeArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE);

private void addSources(MavenProject p, LinkedHashSet<String> sources) {
getLog().debug("Adding sources for " + p.getId());
if (p.getExecutionProject() != null) {
p = p.getExecutionProject();
}
sources.addAll(p.getCompileSourceRoots());
ScopeArtifactFilter artifactFilter = new ScopeArtifactFilter(classpathScope);
for (Artifact artifact : p.getDependencyArtifacts()) {
if (!artifact.getArtifactHandler().isAddedToClasspath()) {
continue;
}
if (!artifactFilter.include(artifact)) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/ltgt/gwt/maven/CodeServerMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
/**
* Runs GWT's CodeServer (SuperDevMode).
*/
@Mojo(name = "codeserver", requiresDependencyResolution = ResolutionScope.COMPILE, requiresDirectInvocation = true, threadSafe = true, aggregator = true)
@Mojo(name = "codeserver", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDirectInvocation = true, threadSafe = true, aggregator = true)
@Execute(phase = LifecyclePhase.PROCESS_CLASSES)
public class CodeServerMojo extends AbstractDevModeMojo {

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/ltgt/gwt/maven/DevModeMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/**
* Runs GWT's DevMode.
*/
@Mojo(name = "devmode", requiresDependencyResolution = ResolutionScope.COMPILE, requiresDirectInvocation = true, threadSafe = true, aggregator = true)
@Mojo(name = "devmode", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDirectInvocation = true, threadSafe = true, aggregator = true)
@Execute(phase = LifecyclePhase.PROCESS_CLASSES)
public class DevModeMojo extends AbstractDevModeMojo {

Expand Down
8 changes: 8 additions & 0 deletions src/site/markdown/codeserver.md.vm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ To run or debug your client-side code, use the [`gwt:codeserver`](codeserver-moj
This is an aggregator goal, which means its configuration is done in your root POM, not in your `gwt-app` (in a multi-module setup).
This gives the goal the opportunity to use several `gwt-app` modules from the reactor (which it will do automatically by default).

Note that `gwt:codeserver` has a slightly different behavior than [`gwt:compile`](compile-mojo.html) to accomodate development needs.
First, all modules from the reactor that are depended on with `<type>gwt-lib</type>` or `<classifier>sources</classifier>` have their source roots used as-is so that changes can be seen immediately;
this means that if anyone of those is declared as a resource directory with filtering or relocation, behavior will different from `gwt:compile`.
Also, dependencies by default use the `runtime` scope, whereas `gwt:compile` uses the `compile` scope;
this allows some differences between `gwt:compile` and `gwt:codeserver` classpaths when needed,
while working in identical ways most of the time (where dependencies are put in the default `compile` scope).
In any case, that behavior is configurable through the `classpathScope` property.

Starting with GWT 2.7, you should set the `launcherDir` property to get _recompile on reload._
The property should point to a folder that you web server / servlet container will look into for web resources,
so that the `*.nocache.js` file generated by the CodeServer can be loaded by your web browser.
Expand Down

0 comments on commit 69ac0f3

Please sign in to comment.