playframework/playframework — pull request #2109 by orrsella (2013-12-11 15:30:06+00:00)
Title: Having a "messages/" directory under resources throws exception during startup, fails app

It seems that having a non-empty `messages/` directory under any of the packaged `resources/` folders (for the play application or *one of the dependency jars*) causes a `Configuration error` and prevents the app from starting.

#### Reproducing

1. Create a new play app
2. Add `conf/messages/foo.ext` (simply adding `messages/` isn't enough, you need to add a file under it)
3. `run`/`start`/`test` the app

(You can also reproduce by creating a new app and adding a dependency jar, which has `src/main/resources/messages/foo.ext`)

#### Stack Trace

```
play> start

(Starting server. Type Ctrl+D to exit logs, the server will remain in background)

Play server process ID is 50664
Oops, cannot start the server.
@6gdk4kp1c: Configuration error in file:/Users/orr/Dev/Projects/play-messages-error/target/scala-2.10/classes/messages:1
at play.api.i18n.Messages$MessagesParser.parse(Messages.scala:219)
at play.api.i18n.MessagesPlugin$$anonfun$play$api$i18n$MessagesPlugin$$loadMessages$1.apply(Messages.scala:286)
at play.api.i18n.MessagesPlugin$$anonfun$play$api$i18n$MessagesPlugin$$loadMessages$1.apply(Messages.scala:285)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at play.api.i18n.MessagesPlugin.play$api$i18n$MessagesPlugin$$loadMessages(Messages.scala:285)
at play.api.i18n.MessagesPlugin.messages$lzycompute(Messages.scala:296)
at play.api.i18n.MessagesPlugin.messages(Messages.scala:292)
at play.api.i18n.MessagesPlugin.onStart(Messages.scala:309)
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88)
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88)
at scala.collection.immutable.List.foreach(List.scala:318)
at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:88)
at play.api.Play$$anonfun$start$1.apply(Play.scala:88)
at play.api.Play$$anonfun$start$1.apply(Play.scala:88)
at play.utils.Threads$.withContextClassLoader(Threads.scala:18)
at play.api.Play$.start(Play.scala:87)
at play.core.StaticApplication.(ApplicationProvider.scala:52)
at play.core.server.NettyServer$.createServer(NettyServer.scala:243)
at play.core.server.NettyServer$$anonfun$main$3.apply(NettyServer.scala:279)
at play.core.server.NettyServer$$anonfun$main$3.apply(NettyServer.scala:274)
at scala.Option.map(Option.scala:145)
at play.core.server.NettyServer$.main(NettyServer.scala:274)
at play.core.server.NettyServer.main(NettyServer.scala)
```

#### Problem Analysis

In `play.api.i18n.DefaultMessagesPlugin` the `messages` method, which gets called by `onStart()` -> `api` -> `messages`, calls `loadMessages("messages")`. `loadMessages` then uses `ClassLoader.getResources("messages")`, which also returns the directory we added to `conf/messages` (or found under any of the `resources/` of our dependency jars). Trying to run `parse` on that `messageFile: URL` results in the exception.

I think the preferred solution would be to only attempt to parse `messages` *files* and not `messages/` *folders*. I'm not sure what's the best way to implement this though.

Leaving the current behavior makes it impossible to use 3rd party jars that have a `resources/messages/` folder, which is how I encountered this error in the first place (and prevents us from using Play at the moment).

I have no problem implementing a fix myself, if we can agree on the best way to safely ignore directory resources.