Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-module-app part 2: classpath resources #506

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

xabolcs
Copy link
Collaborator

@xabolcs xabolcs commented Jan 9, 2025

This is a continuation of #291's second point:

adds support for loading conf, routes etc. from JARs (technically, from classpath), not only from local folders.

The "etc" emphasize is mine! 🙂
In the added hello.html there was a TODO:

  <title>Hello, multi-module RePlay app</title>
<!--  TODO Including files from classpath is not implemented yet -->
<!--  # {include 'icons/favicon.html'/}-->
<!--  # {include './meta.html'/}-->

So I started to implement those missing bits!

More TODOs:

Add IDEA configuration for Multi module app.

While at it, enable "netty3" as backend, but as "runtimeOnly"
dependency to not to interfere with tests.
While the inclusion of 'icons/favicon.html' template itself working,
the referenced '/img/favicon.png' -> 'public/images/favicon.png' file
is served as HTTP 404.
All the PlayHandler.serverStatic() methods uses the common
ServerHelper.findFile().
Let it know how to handle classpath resources with the logic from
play.templates.TemplateLoader.loadTemplateFromClasspath().
While the #{include /} tag worked with the earlier example, it doesn't
work with relative templates.

To reproduce surely, please clean up the tmpDir before testing!
An already existing ./meta.html in the tmpDir will success the test!

play.template2.exceptions.GTRuntimeExceptionWithSourceInfo: Cannot find template ./meta.html
	at /tmp/hello.html.(line:6)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:146)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:110)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.internalRenderTemplate(GTJavaBase1xImpl.java:96)
	at play.template2.GTJavaBase.renderTemplate(GTJavaBase.java:104)
	at play.modules.gtengineplugin.GTTemplate.renderGTTemplate(GTTemplate.java:67)
	at play.modules.gtengineplugin.GTTemplate.internalGTRender(GTTemplate.java:54)
	at play.modules.gtengineplugin.GTTemplate.internalRender(GTTemplate.java:38)
	at play.modules.gtengineplugin.GTTemplate.render(GTTemplate.java:73)
	at play.rebel.View.renderView(View.java:71)
	at play.rebel.View.apply(View.java:50)
	at play.mvc.ActionInvoker.applyResult(ActionInvoker.java:191)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
	at play.server.javanet.PlayHandler$JavaNetInvocation.execute(PlayHandler.java:434)
	at play.server.javanet.PlayHandler$JavaNetInvocation.lambda$run$0(PlayHandler.java:409)
	at play.db.jpa.JPA.withTransaction(JPA.java:271)
	at play.db.jpa.JPA.withinFilter(JPA.java:172)
	at play.server.javanet.PlayHandler$JavaNetInvocation.run(PlayHandler.java:407)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: play.template2.exceptions.GTTemplateRuntimeException: Cannot find template ./meta.html
	at play.template2.compile.GTInternalFastTags.tag_include(GTInternalFastTags.java:119)
	... 24 more
@xabolcs

This comment was marked as outdated.

@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch from 06b3e13 to 71aa0b9 Compare January 9, 2025 03:08
@xabolcs

This comment was marked as outdated.

Copy link
Member

@cies cies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat!

@@ -78,12 +80,32 @@ public GTTemplateLocationReal getTemplateLocationFromRelativePath(String relativ

// TODO find in classpath?
File vf = Play.file(relativePath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think vf here is a remnant of the VirtualFile that's no longer in RePlay. Maybe rename to file?

Copy link
Collaborator Author

@xabolcs xabolcs Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep its a remnant, but I don't care for now!
Maybe I'll add a cleanup commit at the end. 🙂

The referenced configuration files are both on local file system and on
classpath.

20:48:18,288 WARN  [play.PropertiesConfLoader] ~ Missing include: @include.core
java.lang.NullPointerException: File not found in classpath: application.core.conf
	at java.base/java.util.Objects.requireNonNull(Objects.java:336)
	at play.ClasspathResource.<init>(ClasspathResource.java:42)
	at play.ClasspathResource.file(ClasspathResource.java:26)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:52)
	at play.PropertiesConfLoader.resolveIncludes(PropertiesConfLoader.java:143)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:71)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:47)
	at play.PropertiesConfLoader.readConfiguration(PropertiesConfLoader.java:43)
	at play.Play.readConfiguration(Play.java:221)
	at play.Play.start(Play.java:237)
	at hello.HelloWorldApp.start(HelloWorldApp.java:18)
	at hello.HelloWorldApp.main(HelloWorldApp.java:22)
20:48:18,288 WARN  [play.PropertiesConfLoader] ~ Missing include: @include.app
java.lang.NullPointerException: File not found in classpath: application.app.conf
	at java.base/java.util.Objects.requireNonNull(Objects.java:336)
	at play.ClasspathResource.<init>(ClasspathResource.java:42)
	at play.ClasspathResource.file(ClasspathResource.java:26)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:52)
	at play.PropertiesConfLoader.resolveIncludes(PropertiesConfLoader.java:143)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:71)
	at play.PropertiesConfLoader.readOneConfigurationFile(PropertiesConfLoader.java:47)
	at play.PropertiesConfLoader.readConfiguration(PropertiesConfLoader.java:43)
	at play.Play.readConfiguration(Play.java:221)
	at play.Play.start(Play.java:237)
	at hello.HelloWorldApp.start(HelloWorldApp.java:18)
	at hello.HelloWorldApp.main(HelloWorldApp.java:22)
Fixes: 4a43760 ("Add "filePrefix" parameter to play.PropertiesConfLoader")
@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch 2 times, most recently from 1a5cb12 to 6ea9b52 Compare January 19, 2025 20:43
@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch 5 times, most recently from cfb15b1 to 8797d8f Compare February 11, 2025 17:06
Fix Router.reverseWithCheck() calls for classpath resources
with the help of ServerHelper.findFile() and with adding a custom route.

While at it, improve ServerHelper.findFile() to reuse the extracted
classpath resource files.

To prevent unwanted leakage of classpath files, the custom route exposes
only classpath files with path starting with "public/".
This can be improved later.
JavaClassesScanner.allClassesInProject() is used by
Play.classes.getAssignableClasses() extensively:

$ git grep --files-with-matches 'Play.classes.getAssignableClasses('
fastergt/src/play/modules/gtengineplugin/gt_integration/GTFastTagResolver1x.java
fastergt/src/play/modules/gtengineplugin/gt_integration/GTJavaExtensionMethodResolver1x.java
fastergt/src/play/modules/gtengineplugin/gt_integration/GTLegacyFastTagResolver1X.java
framework/src/play/Play.java
framework/src/play/data/binding/Binder.java
framework/src/play/db/jpa/JPAPlugin.java
framework/src/play/jobs/JobsPlugin.java

As the method name "allClassesInProject" says, it only find classes
in the actual project, but not in the dependencies.

Sure, no need to scan all the classpath, but it would be nice to add
a few jars which should be scanned for project classes.

In this example the "jobs.CoreJob" startup job (with @onApplicationStart
annotation) from the "core" module isn't started.

As I don't know how to add HTTP headers to Selenide.download(),
the example adds a new route: /status.txt which renders
the PlayStatusPlugin's output without authorization.
While tags in "app" detected, the tags in "core" are not found:

18:36:39,076 ERROR [play.server.javanet.PlayHandler] ~ Internal Server Error (500) for GET / (GTCompilationExceptionWithSourceInfo)
play.template2.exceptions.GTCompilationExceptionWithSourceInfo: CompilationError: Cannot find tag-implementation for 'core.hello'. Template /my_tmpdir_in_the_workdir/classpathtemplates/hello.html:11
	at play.template2.compile.GTPreCompiler.generateTagCode(GTPreCompiler.java:884)
	at play.template2.compile.GTPreCompiler.processTag(GTPreCompiler.java:727)
	at play.template2.compile.GTPreCompiler.processTag(GTPreCompiler.java:714)
	at play.template2.compile.GTPreCompiler.processNextFragment(GTPreCompiler.java:474)
	at play.template2.compile.GTPreCompiler.internalCompile(GTPreCompiler.java:184)
	at play.template2.compile.GTPreCompiler.compile(GTPreCompiler.java:135)
	at play.template2.compile.GTPreCompiler.compile(GTPreCompiler.java:128)
	at play.template2.compile.GTCompiler.compile(GTCompiler.java:57)
	at play.template2.GTTemplateRepo.compileTemplate(GTTemplateRepo.java:293)
	at play.template2.GTTemplateRepo.getTemplateInstance(GTTemplateRepo.java:181)
	at play.template2.GTTemplateRepo.getTemplateInstance(GTTemplateRepo.java:136)
	at play.modules.gtengineplugin.TemplateLoader.getGTTemplateInstance(TemplateLoader.java:82)
	at play.modules.gtengineplugin.TemplateLoader.load(TemplateLoader.java:75)
	at play.modules.gtengineplugin.GTEnginePlugin.loadTemplate(GTEnginePlugin.java:50)
	at play.plugins.PluginCollection.lambda$loadTemplate$29(PluginCollection.java:340)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at play.plugins.PluginCollection.loadTemplate(PluginCollection.java:342)
	at play.templates.TemplateLoader.load(TemplateLoader.java:42)
	at play.templates.TemplateLoader.getTemplateFromClasspath(TemplateLoader.java:104)
	at play.templates.TemplateLoader.load(TemplateLoader.java:84)
	at play.rebel.View.resolveTemplate(View.java:79)
	at play.rebel.View.renderView(View.java:60)
	at play.rebel.View.apply(View.java:50)
	at play.mvc.ActionInvoker.applyResult(ActionInvoker.java:191)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
	at play.server.javanet.PlayHandler$JavaNetInvocation.execute(PlayHandler.java:434)
	at play.server.javanet.PlayHandler$JavaNetInvocation.lambda$run$0(PlayHandler.java:409)
	at play.db.jpa.JPA.withTransaction(JPA.java:271)
	at play.db.jpa.JPA.withinFilter(JPA.java:172)
	at play.server.javanet.PlayHandler$JavaNetInvocation.run(PlayHandler.java:407)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
To allow the Framework find your project files in your dependencies,
use the "play.classes.scanJars" property in application.conf!

E.g:
play.classes.scanJars=core-*.jar,my-other-optional-dependency-*.jar
@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch from 8797d8f to b2748c7 Compare February 12, 2025 21:03
play.templates.TemplateLoader.loadTemplateFromClasspath() uses
"Play.tmpDir" for extracting files from classpath.
Let use that in this GTFileResolver.Resolver too, with
the "view/" search prefix logic.

The new included "core.html" template and the tests are just
a workaround as the "download()" command doesn't like the GitHub
workflow, so that test is marked as @disabled.

With the fix, the openHelloWorldPage() got timeout in netty4, so it had
to be moved to another spec which is exluded.
This was (unintentionally?) fixed in PR replay-framework#524.

For reference, the original description is below.

Looks like it never worked since its debut in commit
cfe9ff1 ("load "errors/40x.html" templates from classpath").

The serve500 is caused by the "missing" meta.html template, and then
the NPE is caused by the "missing" errors/500.html template:

02:52:45,238 TRACE [play.server.netty4.PlayHandler] ~ serve500: begin
02:52:45,240 ERROR [play.server.netty4.PlayHandler] ~ Internal Server Error (500) for GET / (GTRuntimeExceptionWithSourceInfo)
play.template2.exceptions.GTRuntimeExceptionWithSourceInfo: Cannot find template ./meta.html
	at /tmp/hello.html.(line:6)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:146)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:110)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.internalRenderTemplate(GTJavaBase1xImpl.java:96)
	at play.template2.GTJavaBase.renderTemplate(GTJavaBase.java:104)
	at play.modules.gtengineplugin.GTTemplate.renderGTTemplate(GTTemplate.java:67)
	at play.modules.gtengineplugin.GTTemplate.internalGTRender(GTTemplate.java:54)
	at play.modules.gtengineplugin.GTTemplate.internalRender(GTTemplate.java:38)
	at play.modules.gtengineplugin.GTTemplate.render(GTTemplate.java:73)
	at play.rebel.View.renderView(View.java:71)
	at play.rebel.View.apply(View.java:50)
	at play.mvc.ActionInvoker.applyResult(ActionInvoker.java:191)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
	at play.server.netty4.PlayHandler$Netty4Invocation.execute(PlayHandler.java:278)
	at play.server.netty4.PlayHandler$Netty4Invocation.lambda$run$0(PlayHandler.java:247)
	at play.db.jpa.JPA.withTransaction(JPA.java:271)
	at play.db.jpa.JPA.withinFilter(JPA.java:172)
	at play.server.netty4.PlayHandler$Netty4Invocation.run(PlayHandler.java:245)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: play.template2.exceptions.GTTemplateRuntimeException: Cannot find template ./meta.html
	at play.template2.compile.GTInternalFastTags.tag_include(GTInternalFastTags.java:119)
	... 24 more
02:52:45,242 ERROR [play.server.netty4.PlayHandler] ~ Error during the 500 response generation
java.lang.NullPointerException: Cannot invoke "java.io.File.getAbsolutePath()" because "file" is null
	at play.Play.relativePath(Play.java:376)
	at play.modules.gtengineplugin.TemplateLoader.load(TemplateLoader.java:69)
	at play.modules.gtengineplugin.GTEnginePlugin.loadTemplate(GTEnginePlugin.java:50)
	at play.plugins.PluginCollection.lambda$loadTemplate$29(PluginCollection.java:340)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at play.plugins.PluginCollection.loadTemplate(PluginCollection.java:342)
	at play.templates.TemplateLoader.load(TemplateLoader.java:35)
	at play.templates.TemplateLoader.loadTemplateFromClasspath(TemplateLoader.java:95)
	at play.templates.TemplateLoader.load(TemplateLoader.java:82)
	at play.server.ServerHelper.generateErrorResponse(ServerHelper.java:83)
	at play.server.netty4.PlayHandler.serve500(PlayHandler.java:625)
	at play.server.netty4.PlayHandler$Netty4Invocation.run(PlayHandler.java:260)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
02:52:45,242 TRACE [play.server.netty4.PlayHandler] ~ serve500: end

Refs: a6db7e1 ("fix concurrency issue in TemplateLoader")
play.templates.TemplateLoader.getTemplateFromClasspath() stores the
found templates in the root of Play.tmpDir.
Let's store them in the TemplateLoader's own subdirectory!
Tag '@{...}' is for reverse routing, see documentation:
https://www.playframework.com/documentation/1.5.x/templates#Actionsor

Calling '@{...}' with a resource on a classpath fails with
play.exceptions.NoRouteFoundException:

09:54:56,765 ERROR [play.server.javanet.PlayHandler] ~ Internal Server Error (500) for GET / (GTAppClassException)
play.template2.exceptions.GTAppClassException: No route found to display file /public/images/favicon.png (file not found)
	at play.mvc.Router.reverseWithCheck(Router.java:306)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.__reverseWithCheck(GTJavaBase1xImpl.java:42)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.__reverseWithCheck_absolute_false(GTJavaBase1xImpl.java:38)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:146)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:110)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.internalRenderTemplate(GTJavaBase1xImpl.java:96)
	at play.template2.compile.GTInternalFastTags.tag_include(GTInternalFastTags.java:127)
	at /my_tmpdir_in_the_workdir/classpathtemplates/hello.html.(line:5)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:146)
	at play.template2.GTJavaBase.internalRenderTemplate(GTJavaBase.java:110)
	at play.modules.gtengineplugin.gt_integration.GTJavaBase1xImpl.internalRenderTemplate(GTJavaBase1xImpl.java:96)
	at play.template2.GTJavaBase.renderTemplate(GTJavaBase.java:104)
	at play.modules.gtengineplugin.GTTemplate.renderGTTemplate(GTTemplate.java:67)
	at play.modules.gtengineplugin.GTTemplate.internalGTRender(GTTemplate.java:54)
	at play.modules.gtengineplugin.GTTemplate.internalRender(GTTemplate.java:38)
	at play.modules.gtengineplugin.GTTemplate.render(GTTemplate.java:73)
	at play.rebel.View.renderView(View.java:71)
	at play.rebel.View.apply(View.java:50)
	at play.mvc.ActionInvoker.applyResult(ActionInvoker.java:191)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
	at play.server.javanet.PlayHandler$JavaNetInvocation.execute(PlayHandler.java:434)
	at play.server.javanet.PlayHandler$JavaNetInvocation.lambda$run$0(PlayHandler.java:409)
	at play.db.jpa.JPA.withTransaction(JPA.java:271)
	at play.db.jpa.JPA.withinFilter(JPA.java:172)
	at play.server.javanet.PlayHandler$JavaNetInvocation.run(PlayHandler.java:407)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: play.template2.exceptions.GTAppClassException: No route found to display file /public/images/favicon.png (file not found)
	... 31 more
Caused by: play.exceptions.NoRouteFoundException: No route found to display file /public/images/favicon.png (file not found)
	... 31 more
@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch 2 times, most recently from 8b0cf08 to 80ddb6e Compare February 13, 2025 09:19
@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch from 80ddb6e to 4538c99 Compare February 13, 2025 21:04
@xabolcs
Copy link
Collaborator Author

xabolcs commented Feb 13, 2025

@asolntsev ,

I already added a test with custom play.tmpDir but wanted a second batch of test with play.tmpDir=none:

22:00:28,855 DEBUG [play.Play] ~ No tmp folder will be used (play.tmp is set to none)

How could I do this without duplicating all the test? Or at least, make only the minimal duplications. 🤔

@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch 3 times, most recently from 77e663a to 09405a8 Compare February 14, 2025 20:10
@@ -87,7 +87,7 @@ public GTTemplateLocationReal getTemplateLocationFromRelativePath(String relativ
URL url = null;
if (vf == null) {
try {
final String classloadedPrefix = "/" + Play.tmpDir.getName() + "/";
final String classloadedPrefix = "/" + Play.tmpDir.getName() + "/" + TemplateLoader.CLASSPATH_LOADED_TEMPLATE_TMP_PATH_PREFIX;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dies with NPE when play.tmpDir=none is set in the application.conf, but a fix is ready, just a few tests need to be cooked.

@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch from 09405a8 to 8d33fd9 Compare February 14, 2025 20:26
@asolntsev
Copy link
Contributor

How could I do this without duplicating all the test? Or at least, make only the minimal duplications. 🤔

Maybe it's not worth that? Maybe just don't test custom play.tmpDir... :)

@xabolcs
Copy link
Collaborator Author

xabolcs commented Feb 25, 2025

Thanks!
I'm going to finalize this PR in the next days and mark it ready to review. 👌

@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch 2 times, most recently from cf906cd to 9c87a64 Compare February 26, 2025 01:32
@xabolcs xabolcs marked this pull request as ready for review February 26, 2025 01:35
@xabolcs xabolcs requested review from cies and asolntsev February 26, 2025 01:36
@xabolcs
Copy link
Collaborator Author

xabolcs commented Feb 26, 2025

This PR is now ready to review.

The commit order is the following (separated by hand):

$ git log --oneline master..HEAD | tac

f6821ff replay-tests: multi-module-app: let it run

532c7a1 replay-tests: enable failing example for static file on classpath
ff8162d serveStatic: improve ServerHelper.findFile() with classpath

2ce3c56 replay-tests: enable failing example for relative template on classpath
49f6990 fastergt: gt_integration: resolve relative templates from classpath

26fd766 replay-tests: add (now fixed) example for classpath with custom tmpDir
4f7e74d framework: move the classpath-loaded templates to their own dir

afe870f replay-tests: add failing example with '@' for resources on classpath
28ede40 framework: fix Router.reverseWithCheck() calls with classpath files

c60b791 replay-tests: add failing example for allClassesInProject() on classpath
1c7162e replay-tests: add failing tests for FastTags and GTFastTag on classpath
d2aae17 framework: add jar classes from "play.classes.scanJars" property

20718e9 replay-tests: add failing tests for @include with /conf prefix
8016983 framework: use "filePrefix" for relative config files @include

@xabolcs xabolcs force-pushed the play-modules-and-classpath-resources-aka-multi-module-app-part2 branch from 9c87a64 to 8016983 Compare February 27, 2025 11:02
Copy link
Member

@cies cies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants