Skip to content

Commit 5216c44

Browse files
committed
assets bugs
* dont fail when asset pipeline is empty fix #392 * closure compiler attempt to process .css files (not .js) fix #391 * assets maven plugin is broken fix #390
1 parent eb6f668 commit 5216c44

12 files changed

Lines changed: 97 additions & 46 deletions

File tree

jooby-assets-closure-compiler/src/main/java/org/jooby/assets/ClosureCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public class ClosureCompiler extends AssetProcessor {
9292

9393
@Override
9494
public boolean matches(final MediaType type) {
95-
return MediaType.css.matches(type);
95+
return MediaType.js.matches(type);
9696
}
9797

9898
@Override

jooby-assets-closure-compiler/src/test/java/org/jooby/assets/ClosureCompilerTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.FileNotFoundException;
66
import java.util.Arrays;
77

8+
import org.jooby.MediaType;
89
import org.junit.Test;
910

1011
import com.typesafe.config.ConfigFactory;
@@ -69,4 +70,9 @@ public void error() throws Exception {
6970
ConfigFactory.empty()));
7071
}
7172

73+
@Test
74+
public void ctype() throws Exception {
75+
assertEquals(true, new ClosureCompiler().matches(MediaType.js));
76+
}
77+
7278
}

jooby-assets/src/main/java/org/jooby/assets/AssetCompiler.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,32 +147,35 @@ public List<String> styles(final String name) {
147147
public List<AssetProcessor> pipeline(final String dist) {
148148
List<AssetProcessor> chain = this.pipeline.get(dist);
149149
if (chain == null) {
150-
throw new IllegalArgumentException("No pipeline for: " + dist);
150+
log.debug("no pipeline for: {}", dist);
151+
return Collections.emptyList();
151152
}
152153
return chain;
153154
}
154155

155156
public Map<String, List<File>> build(final String dist, final File dir) throws Exception {
156157
Map<String, List<File>> output = new LinkedHashMap<>();
158+
List<AssetProcessor> pipeline = pipeline(dist);
159+
log.info("{} pipeline: {}", dist, pipeline);
157160
for (String fset : keySet()) {
158161
List<String> files = assets(fset);
159162

160-
log.info("compiling {}: ", fset);
163+
log.info("compiling {}:", fset);
161164

162-
String css = compile(dist, files.stream().filter(styles).iterator(), MediaType.css, "");
165+
String css = compile(pipeline, files.stream().filter(styles).iterator(), MediaType.css, "");
163166
Path pcss = Paths.get(patterns(styles).findFirst().get(), fset + "." + sha1(css) + ".css");
164167
File fcss = dir.toPath().resolve(pcss).toFile();
165168
fcss.getParentFile().mkdirs();
166169
Files.write(css, fcss, charset);
167170

168-
String js = compile(dist, files.stream().filter(scripts).iterator(), MediaType.js, ";");
171+
String js = compile(pipeline, files.stream().filter(scripts).iterator(), MediaType.js, ";");
169172
Path pjs = Paths.get(patterns(scripts).findFirst().get(), fset + "." + sha1(js) + ".js");
170173
File fjs = dir.toPath().resolve(pjs).toFile();
171174
fjs.getParentFile().mkdirs();
172175
Files.write(js, fjs, charset);
173176

174-
log.info("{}", fcss);
175-
log.info("{}", fjs);
177+
log.info("{}.css {} ({})", fset, humanReadableByteCount(fcss.length()), fcss);
178+
log.info("{}.js {} ({})", fset, humanReadableByteCount(fjs.length()), fjs);
176179

177180
output.put(fset, Arrays.asList(fcss, fjs));
178181
}
@@ -196,7 +199,8 @@ public Asset build(final Asset asset) throws Exception {
196199
return asset;
197200
}
198201

199-
String output = compile("dev", filename, type, toString(asset.stream(), charset));
202+
List<AssetProcessor> pipeline = pipeline("dev");
203+
String output = compile(pipeline, filename, type, toString(asset.stream(), charset));
200204

201205
return new InMemoryAsset(asset, output.getBytes(charset));
202206
}
@@ -214,22 +218,21 @@ private Stream<String> patterns(final Predicate<String> filter) {
214218

215219
}
216220

217-
private String compile(final String env, final Iterator<String> files, final MediaType type,
218-
final String sep)
219-
throws Exception {
221+
private String compile(final List<AssetProcessor> pipeline, final Iterator<String> files,
222+
final MediaType type, final String sep) throws Exception {
220223
StringBuilder buff = new StringBuilder();
221224
while (files.hasNext()) {
222225
String file = files.next();
223226
log.info(" {}", file);
224-
buff.append(compile(env, file, type, readFile(loader, file, charset))).append(sep);
227+
buff.append(compile(pipeline, file, type, readFile(loader, file, charset))).append(sep);
225228
}
226229
return buff.toString();
227230
}
228231

229-
private String compile(final String env, final String filename, final MediaType type,
230-
final String input) throws Exception {
232+
private String compile(final List<AssetProcessor> pipeline, final String filename,
233+
final MediaType type, final String input) throws Exception {
231234

232-
Iterator<AssetProcessor> it = pipeline(env).iterator();
235+
Iterator<AssetProcessor> it = pipeline.iterator();
233236
String contents = input;
234237
while (it.hasNext()) {
235238
AssetProcessor processor = it.next();
@@ -430,4 +433,14 @@ private static String spath(final String path) {
430433
return path.startsWith("/") ? path : "/" + path;
431434
}
432435

436+
private static String humanReadableByteCount(final long bytes) {
437+
int unit = 1024;
438+
if (bytes < unit) {
439+
return bytes + "b";
440+
}
441+
int exp = (int) (Math.log(bytes) / Math.log(unit));
442+
char pre = "kmgtpe".charAt(exp - 1);
443+
return String.format("%.1f%sb", bytes / Math.pow(unit, exp), pre);
444+
}
445+
433446
}

jooby-assets/src/main/java/org/jooby/assets/Assets.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.jooby.assets;
2020

2121
import java.time.Duration;
22+
import java.util.concurrent.TimeUnit;
2223

2324
import org.jooby.Env;
2425
import org.jooby.Jooby;
@@ -269,7 +270,8 @@ public void configure(final Env env, final Config config, final Binder binder) {
269270
.lastModified(conf.getBoolean("assets.lastModified"));
270271

271272
if (conf.hasPath("assets.cache.maxAge")) {
272-
handler.maxAge(Duration.parse(conf.getString("assets.cache.maxAge")));
273+
handler.maxAge(Duration
274+
.ofSeconds(conf.getDuration("assets.cache.maxAge", TimeUnit.SECONDS)));
273275
}
274276

275277
compiler.patterns().forEach(

jooby-assets/src/test/java/org/jooby/assets/AssetCompilerTest.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertNotNull;
55
import static org.junit.Assert.assertTrue;
6-
import static org.junit.Assert.fail;
76

87
import java.io.File;
98
import java.io.FileNotFoundException;
109
import java.nio.file.Paths;
1110
import java.util.Arrays;
11+
import java.util.Collections;
1212
import java.util.List;
1313
import java.util.Map;
1414

@@ -176,12 +176,8 @@ public void pipeline() throws Exception {
176176
assertEquals("foo", prod.iterator().next().get("foo"));
177177
assertEquals("bar", prod.iterator().next().get("bar"));
178178

179-
try {
180-
compiler.pipeline("prod");
181-
fail("no pipeline");
182-
} catch (IllegalArgumentException ex) {
183-
184-
}
179+
List<AssetProcessor> pipeline = compiler.pipeline("prod");
180+
assertEquals(Collections.emptyList(), pipeline);
185181
}
186182

187183
private String compile(final AssetCompiler compiler, final String path) throws Exception {

jooby-assets/src/test/java/org/jooby/assets/AssetsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public void configuredist() throws Exception {
182182
.withValue("assets.etag", ConfigValueFactory.fromAnyRef(true))
183183
.withValue("application.path", ConfigValueFactory.fromAnyRef("/"))
184184
.withValue("assets.cdn", ConfigValueFactory.fromAnyRef(""))
185-
.withValue("assets.cache.maxAge", ConfigValueFactory.fromAnyRef("P365D"))
185+
.withValue("assets.cache.maxAge", ConfigValueFactory.fromAnyRef("365d"))
186186
.withValue("assets.lastModified", ConfigValueFactory.fromAnyRef(true))
187187
.withValue("assets.watch", ConfigValueFactory.fromAnyRef(false));
188188
new MockUnit(Env.class, Config.class, Binder.class, Request.class, Response.class,
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package org.jooby.assets;
22

3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
38
import org.junit.Test;
49

10+
import com.google.common.collect.Sets;
511
import com.typesafe.config.ConfigFactory;
612

713
public class Issue229 {
814

915
@Test
1016
public void wrongVars() throws Exception {
1117
AssetCompiler compiler = new AssetCompiler(ConfigFactory.parseResources("issue.229.conf"));
18+
Set<String> vars = new HashSet<>();
1219
compiler.keySet().forEach(asset -> {
13-
System.out.println(asset);
20+
vars.add(asset);
1421
});
22+
23+
assertEquals(Sets.newHashSet("form", "base"), vars);
1524
}
1625
}

jooby-maven-plugin/src/main/java/org/jooby/AssetMojo.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
import com.typesafe.config.Config;
4444
import com.typesafe.config.ConfigFactory;
4545

46-
@Mojo(name = "assets", requiresDependencyResolution = ResolutionScope.TEST,
47-
defaultPhase = LifecyclePhase.PREPARE_PACKAGE)
48-
@Execute(phase = LifecyclePhase.PREPARE_PACKAGE)
46+
@Mojo(name = "assets", defaultPhase = LifecyclePhase.COMPILE,
47+
requiresDependencyResolution = ResolutionScope.TEST)
48+
@Execute(phase = LifecyclePhase.COMPILE)
4949
public class AssetMojo extends AbstractMojo {
5050

5151
@SuppressWarnings("serial")
@@ -78,9 +78,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
7878
System.setProperty("application.env", env);
7979

8080
new JoobyRunner(mavenProject)
81-
.run(mainClass, (app, loader) -> {
82-
app.on("*", compile(loader));
83-
});
81+
.run(mainClass, app -> {
82+
app.on("*", compile(app.getClass().getClassLoader()));
83+
});
8484
} catch (CompilationDone ex) {
8585
long end = System.currentTimeMillis();
8686
getLog().info("compilation took " + (end - start) + "ms");
@@ -94,9 +94,13 @@ private Consumer<Config> compile(final ClassLoader loader) {
9494
try {
9595
output.mkdirs();
9696

97+
getLog().debug("claspath: " + loader);
98+
9799
Config assetConf = ConfigFactory.parseResources(loader, "assets.conf")
98100
.withFallback(conf);
99101

102+
getLog().debug("assets.conf: " + assetConf.getConfig("assets"));
103+
100104
AssetCompiler compiler = new AssetCompiler(loader, assetConf);
101105

102106
Map<String, List<File>> fileset = compiler.build(env, output);

jooby-maven-plugin/src/main/java/org/jooby/Classpath.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,16 @@ public List<URL> build() throws MalformedURLException {
6161
}
6262

6363
public URLClassLoader toClassLoader() throws MalformedURLException {
64-
return new URLClassLoader(build().toArray(new URL[0]), getClass().getClassLoader());
64+
return toClassLoader(build(), getClass().getClassLoader());
65+
}
66+
67+
private static URLClassLoader toClassLoader(final List<URL> cp, final ClassLoader parent) {
68+
return new URLClassLoader(cp.toArray(new URL[cp.size()]), parent) {
69+
@Override
70+
public String toString() {
71+
return cp.toString();
72+
}
73+
};
6574
}
6675

6776
private List<URL> jars(final Iterable<Artifact> artifacts) throws MalformedURLException {

jooby-maven-plugin/src/main/java/org/jooby/JoobyRunner.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
import java.net.URLClassLoader;
3636
import java.util.List;
37-
import java.util.function.BiConsumer;
3837
import java.util.function.Consumer;
3938

4039
import org.apache.maven.project.MavenProject;
@@ -56,19 +55,14 @@ public JoobyRunner with(final Consumer<List<Route.Definition>> callback) {
5655

5756
public void run(final String mainClass, final Consumer<Jooby> callback)
5857
throws Throwable {
59-
run(mainClass, (app, loader) -> callback.accept(app));
60-
}
61-
62-
public void run(final String mainClass, final BiConsumer<Jooby, ClassLoader> callback)
63-
throws Throwable {
64-
ClassLoader loader = Thread.currentThread().getContextClassLoader();
65-
try (URLClassLoader apploader = cp.toClassLoader()) {
66-
Thread.currentThread().setContextClassLoader(apploader);
67-
Jooby app = (Jooby) apploader.loadClass(mainClass).newInstance();
68-
callback.accept(app, loader);
58+
ClassLoader global = Thread.currentThread().getContextClassLoader();
59+
try (URLClassLoader local = cp.toClassLoader()) {
60+
Thread.currentThread().setContextClassLoader(local);
61+
Jooby app = (Jooby) local.loadClass(mainClass).newInstance();
62+
callback.accept(app);
6963
app.start(routes);
7064
} finally {
71-
Thread.currentThread().setContextClassLoader(loader);
65+
Thread.currentThread().setContextClassLoader(global);
7266
}
7367
}
7468

0 commit comments

Comments
 (0)