diff --git a/framework/build.xml b/framework/build.xml
index 5b02f0c075..8b29e48408 100644
--- a/framework/build.xml
+++ b/framework/build.xml
@@ -302,6 +302,10 @@
+
+
+
+
diff --git a/framework/src/play/templates/GroovyTemplateCompiler.java b/framework/src/play/templates/GroovyTemplateCompiler.java
index 85571609cf..d1bbf35466 100644
--- a/framework/src/play/templates/GroovyTemplateCompiler.java
+++ b/framework/src/play/templates/GroovyTemplateCompiler.java
@@ -362,8 +362,8 @@ protected void endTag() {
} catch (Exception e) {
// Use fastTag if exists
List fastClasses = new ArrayList<>();
- fastClasses.add(FastTags.class);
fastClasses.addAll(Play.classloader.getAssignableClasses(FastTags.class));
+ fastClasses.add(FastTags.class);
Method m = null;
String tName = tag.name;
diff --git a/samples-and-tests/fast-tag/app/controllers/Application.java b/samples-and-tests/fast-tag/app/controllers/Application.java
new file mode 100644
index 0000000000..58f407aee4
--- /dev/null
+++ b/samples-and-tests/fast-tag/app/controllers/Application.java
@@ -0,0 +1,16 @@
+package controllers;
+
+import play.*;
+import play.mvc.*;
+
+import java.util.*;
+
+import models.*;
+
+public class Application extends Controller {
+
+ public static void index() {
+ render();
+ }
+
+}
\ No newline at end of file
diff --git a/samples-and-tests/fast-tag/app/tags/OverridenFastTag.java b/samples-and-tests/fast-tag/app/tags/OverridenFastTag.java
new file mode 100644
index 0000000000..4945517534
--- /dev/null
+++ b/samples-and-tests/fast-tag/app/tags/OverridenFastTag.java
@@ -0,0 +1,21 @@
+package tags;
+
+import groovy.lang.Closure;
+import play.templates.FastTags;
+import play.templates.GroovyTemplate.ExecutableTemplate;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@FastTags.Namespace
+public class OverridenFastTag extends FastTags {
+
+ public static void _field(Map, ?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
+ Map field = new HashMap();
+ field.put("id", "overriden");
+ body.setProperty("field", field);
+ body.call();
+ }
+}
diff --git a/samples-and-tests/fast-tag/app/views/Application/index.html b/samples-and-tests/fast-tag/app/views/Application/index.html
new file mode 100644
index 0000000000..899eaa4191
--- /dev/null
+++ b/samples-and-tests/fast-tag/app/views/Application/index.html
@@ -0,0 +1 @@
+#{form @index()}#{field 'id'}${field.id}#{/field}#{/form}
\ No newline at end of file
diff --git a/samples-and-tests/fast-tag/conf/application.conf b/samples-and-tests/fast-tag/conf/application.conf
new file mode 100644
index 0000000000..73da6bc005
--- /dev/null
+++ b/samples-and-tests/fast-tag/conf/application.conf
@@ -0,0 +1,260 @@
+# This is the main configuration file for the application.
+# ~~~~~
+application.name=fast-tag
+
+# Application mode
+# ~~~~~
+# Set to dev to enable instant reloading and other development help.
+# Otherwise set to prod.
+application.mode=dev
+%prod.application.mode=prod
+
+# Secret key
+# ~~~~~
+# The secret key is used to secure cryptographics functions
+# If you deploy your application to several instances be sure to use the same key !
+application.secret=sNpGP3Eq6oQ2f2SdwSnXmHxoAynjFDoNp4MowvnXYf4dDvWBmRRUBRdNIqVCptsM
+
+# i18n
+# ~~~~~
+# Define locales used by your application.
+# You can then place localized messages in conf/messages.{locale} files
+# application.langs=fr,en,ja
+
+# Date format
+# ~~~~~
+date.format=yyyy-MM-dd
+# date.format.fr=dd/MM/yyyy
+
+# Server configuration
+# ~~~~~
+# If you need to change the HTTP port, uncomment this (default is set to 9000)
+# http.port=9000
+#
+# By default the server listen for HTTP on the wildcard address.
+# You can restrict this.
+# http.address=127.0.0.1
+#
+# Use this if you don't host your Play application at the root of the domain
+# you're serving it from. This parameter has no effect when deployed as a
+# war, because the path will be handled by the application server.
+# http.path=/
+
+# Session configuration
+# ~~~~~~~~~~~~~~~~~~~~~~
+# By default, session will be written to the transient PLAY_SESSION cookie.
+# The cookies are not secured by default, only set it to true
+# if you're serving your pages through https.
+# application.session.cookie=PLAY
+# application.session.maxAge=1h
+# application.session.secure=false
+
+# Session/Cookie sharing between subdomain
+# ~~~~~~~~~~~~~~~~~~~~~~
+# By default a cookie is only valid for a specific domain. By setting
+# application.defaultCookieDomain to '.example.com', the cookies
+# will be valid for all domains ending with '.example.com', ie:
+# foo.example.com and bar.example.com
+# application.defaultCookieDomain=.example.com
+
+# JVM configuration
+# ~~~~~
+# Define which port is used by JPDA when application is in debug mode (default is set to 8000)
+# jpda.port=8000
+#
+# Java source level => 1.8
+# java.source=1.8
+
+# Log level
+# ~~~~~
+# Specify log level for your application.
+# If you want a very customized log, create a log4j.properties file in the conf directory
+# application.log=INFO
+#
+# More logging configuration
+# application.log.path=/log4j.properties
+# application.log.system.out=off
+
+# Database configuration
+# ~~~~~
+# Enable a database engine if needed.
+#
+# To quickly set up a development database, use either:
+# - mem : for a transient in memory database (H2 in memory)
+# - fs : for a simple file written database (H2 file stored)
+# db.default=mem
+#
+# To connect to a local MySQL5 database, use:
+# db.default=mysql://user:pwd@host/database
+#
+# To connect to a local PostgreSQL9 database, use:
+# db=postgres://user:pwd@host/database
+#
+# If you need a full JDBC configuration use the following :
+# db.default.url=jdbc:postgresql:database_name
+# db.default.driver=org.postgresql.Driver
+# db.default.user=root
+# db.default.pass=secret
+#
+# Connections pool configuration :
+# db.default.pool.timeout=1000
+# db.default.pool.maxSize=30
+# db.default.pool.minSize=10
+#
+# If you want to reuse an existing Datasource from your application server, use:
+# db.default=java:/comp/env/jdbc/myDatasource
+#
+# When using an existing Datasource, it's sometimes needed to destroy it when
+# the application is stopped. Depending on the datasource, you can define a
+# generic "destroy" method :
+# db.default.destroyMethod=close
+
+# # database isolation configuration
+# # Valid values are NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE,
+# # or an integer value to be passed to java.sql.Connection.setTransactionIsolation().
+# # Note that not all databases support all transaction isolation levels.
+# # Default: database dependent, usually READ_COMMITTED
+# db.default.isolation=SERIALIZABLE
+
+# JPA Configuration (Hibernate)
+# ~~~~~
+#
+# Specify the custom JPA dialect to use here (default to guess):
+# jpa.default.dialect=org.hibernate.dialect.PostgreSQLDialect
+#
+# Specify the ddl generation pattern to use. Set to none to disable it
+# (default to update in DEV mode, and none in PROD mode):
+# jpa.default.ddl=update
+#
+# Debug SQL statements (logged using DEBUG level):
+# jpa.default.debugSQL=true
+#
+# You can even specify additional hibernate properties here:
+# hibernate.default.use_sql_comments=true
+# ...
+# org.hibernate.default.flushMode
+# javax.persistence.default.flushMode
+#
+
+# Store path for Blob content
+attachments.path=data/attachments
+
+# Memcached configuration
+# ~~~~~
+# Enable memcached if needed. Otherwise a local cache is used.
+# memcached=enabled
+#
+# Specify memcached host (default to 127.0.0.1:11211)
+# memcached.host=127.0.0.1:11211
+#
+# Or you can specify multiple host to build a distributed cache
+# memcached.1.host=127.0.0.1:11211
+# memcached.2.host=127.0.0.1:11212
+#
+# Use plain SASL to authenticate for memcached
+# memcached.user=
+# memcached.password=
+
+# HTTP Response headers control for static files
+# ~~~~~
+# Set the default max-age, telling the user's browser how long it should cache the page.
+# Default is 3600 (one hour). Set it to 0 to send no-cache.
+# This is only read in prod mode, in dev mode the cache is disabled.
+# http.cacheControl=3600
+
+# If enabled, Play will generate entity tags automatically and send a 304 when needed.
+# Default is true, set it to false to deactivate use of entity tags.
+# http.useETag=true
+
+# Custom mime types
+# mimetype.xpi=application/x-xpinstall
+
+# WS configuration
+# ~~~~~
+# Default engine is Async Http Client, uncomment to use
+# the JDK's internal implementation
+# webservice = urlfetch
+# If you need to set proxy params for WS requests
+# http.proxyHost = localhost
+# http.proxyPort = 3128
+# http.proxyUser = jojo
+# http.proxyPassword = jojo
+
+# Mail configuration
+# ~~~~~
+# Default is to use a mock Mailer
+mail.smtp=mock
+
+# Or, specify mail host configuration
+# mail.smtp.host=127.0.0.1
+# mail.smtp.user=admin
+# mail.smtp.pass=
+# mail.smtp.channel=ssl
+
+# Url-resolving in Jobs
+# ~~~~~~
+# When rendering templates with reverse-url-resoling (@@{..}) in Jobs (which do not have an inbound Http.Request),
+# ie if sending a HtmlMail, Play need to know which url your users use when accessing your app.
+# %test.application.baseUrl=http://localhost:9000/
+# %prod.application.baseUrl=http://www.yourdomain.com/
+
+# Templates additional precompilation
+# ~~~~~~
+# yaml files can use template expressions and are located in the conf folder.
+# The default precompile task will not pickup those files.
+# You can manually add some files with the following property
+# (default: system property play.templates.compile, fallback system environment PLAY_TEMPLATES_COMPILE)
+# play.templates.compile=conf/initialdata.yml;{module:reporting}test/reporting/unittests/export.yml
+#
+# Override the path separator if you want to use the Play!-module notation like {module:modname} on unix.
+# (default: system property path.separator)
+# play.templates.compile.path.separator=;
+
+# Jobs executor
+# ~~~~~~
+# Size of the Jobs pool
+# play.jobs.pool=10
+
+# Execution pool
+# ~~~~~
+# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
+# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
+# play.pool=3
+
+# Netty pipeline configuration (advanced settings)
+# You can default netty settings by overriding the following line. Each handler must be comma separated.
+# The last value must be the PlayHandler class (or your own that extends PlayHandler)
+# Default values are
+# play.netty.pipeline = play.server.FlashPolicyHandler,org.jboss.netty.handler.codec.http.HttpRequestDecoder,play.server.StreamChunkAggregator,org.jboss.netty.handler.codec.http.HttpResponseEncoder,org.jboss.netty.handler.stream.ChunkedWriteHandler,play.server.PlayHandler
+# For example, to enable Netty response compression
+# play.netty.pipeline = play.server.FlashPolicyHandler,org.jboss.netty.handler.codec.http.HttpRequestDecoder,play.server.StreamChunkAggregator,org.jboss.netty.handler.codec.http.HttpResponseEncoder,org.jboss.netty.handler.codec.http.HttpContentCompressor,org.jboss.netty.handler.stream.ChunkedWriteHandler,play.server.PlayHandler
+# For SSL, use the play.ssl.netty.pipeline property
+# play.ssl.netty.pipeline = play.server.FlashPolicyHandler,org.jboss.netty.handler.codec.http.HttpRequestDecoder,play.server.StreamChunkAggregator,org.jboss.netty.handler.codec.http.HttpResponseEncoder,org.jboss.netty.handler.codec.http.HttpContentCompressor,org.jboss.netty.handler.stream.ChunkedWriteHandler,play.server.ssl.SslPlayHandler
+
+# # X509 certificates
+# # the following values are default values
+# certificate.key.file=conf/host.key
+# # certificate.password used only if certificate.key.file is password protected
+# certificate.password=secret
+# certificate.file=conf/host.cert
+# trustmanager.algorithm=JKS
+# keystore.algorithm=JKS
+# keystore.password=secret
+# keystore.file=conf/certificate.jks
+
+# Open file from errors pages
+# ~~~~~
+# If your text editor supports opening files by URL, Play! will
+# dynamically link error pages to files
+#
+# Example, for textmate:
+# play.editor=txmt://open?url=file://%s&line=%s
+
+# Testing. Set up a custom configuration for test mode
+# ~~~~~
+#%test.module.cobertura=${play.path}/modules/cobertura
+%test.application.mode=dev
+%test.db.url=jdbc:h2:mem:play;MODE=MYSQL;LOCK_MODE=0
+%test.jpa.ddl=create
+%test.mail.smtp=mock
+
diff --git a/samples-and-tests/fast-tag/conf/dependencies.yml b/samples-and-tests/fast-tag/conf/dependencies.yml
new file mode 100644
index 0000000000..85373765a1
--- /dev/null
+++ b/samples-and-tests/fast-tag/conf/dependencies.yml
@@ -0,0 +1,4 @@
+# Application dependencies
+
+require:
+ - play
diff --git a/samples-and-tests/fast-tag/conf/messages b/samples-and-tests/fast-tag/conf/messages
new file mode 100644
index 0000000000..b51f29459d
--- /dev/null
+++ b/samples-and-tests/fast-tag/conf/messages
@@ -0,0 +1,3 @@
+# You can specialize this file for each language.
+# For example, for French create a messages.fr file
+#
diff --git a/samples-and-tests/fast-tag/conf/routes b/samples-and-tests/fast-tag/conf/routes
new file mode 100644
index 0000000000..53a1b03aa1
--- /dev/null
+++ b/samples-and-tests/fast-tag/conf/routes
@@ -0,0 +1,2 @@
+GET / Application.index
+GET /public staticDir:public
\ No newline at end of file
diff --git a/samples-and-tests/fast-tag/test/OverridenFastTagTest.java b/samples-and-tests/fast-tag/test/OverridenFastTagTest.java
new file mode 100644
index 0000000000..32803254a0
--- /dev/null
+++ b/samples-and-tests/fast-tag/test/OverridenFastTagTest.java
@@ -0,0 +1,16 @@
+import org.junit.*;
+import play.test.*;
+import play.mvc.*;
+import play.mvc.Http.*;
+import models.*;
+
+public class OverridenFastTagTest extends FunctionalTest {
+
+ @Test
+ public void testThatIndexPageWorks() {
+ Response response = GET("/");
+ assertIsOk(response);
+ assertContentMatch("overriden", response);
+ }
+
+}
\ No newline at end of file