Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot resolve symbol routes

What's the problem with this "routes" that are not found in IntelliJ IDEA 14?

Here

like image 338
Ochirbold Manal Avatar asked Nov 21 '14 14:11

Ochirbold Manal


2 Answers

According to the documentation:

For each controller used in the routes file, the router will generate a ‘reverse controller’ in the routes package, having the same action methods, with the same signature, but returning a play.mvc.Call instead of a play.mvc.Result.

Reverse controllers are generated when an application is compiled. It follows that you need to compile your application in order to make these classes accessible in your IDE. To make sure that Idea finds files correctly you can right-click target's subdirectory which contains generated classes and mark it as a source directory.

like image 163
Daniel Olszewski Avatar answered Oct 06 '22 19:10

Daniel Olszewski


I've hit this problem a few times. For me, the project would compile with sbt, but Intellij had trouble resolving references. Here are some causes I've found:


Cause 1: Namespace Confusion

One cause for this I have hit a couple of times is that Intellij gets confused about namespaces due to some wildcard imports - it's not actually related to project configuration.

For example, we've found that if you import play.api._, then Intellij won't be able to resolve import controllers.routes (or anything else in controllers). If you switch them around though, it's okay.

You can test if this is the problem by moving your imports around, or seeing if the same imports work in different files.

To check if Intellij really can't resolve your class, try referencing the class from _root_. With my example above, Intellij was always able to resolve _root_.controllers.routes, so I knew it wasn't an issue related to how my project was configured.

(I wouldn't leave that _root_ in the code though, it's a bit ugly and confusing I think! Someone will just delete it and then the problem will come back. Instead I'd try to remove wild card imports)


Cause 2: generated sources aren't marked as "Sources"

Classes like routes and other template classes inside view are auto-generated. It's possible the project isn't configured correctly and Intellij doesn't realize that there are auto-generated routes and twirl source files.

On my system, those auto-generated folders live in target/scala-[VERSION]/ as src_managed (all the routes stuff) and twirl (all the templates stuff).

To check/fix this, do:

  • File -> Project Structure
  • select "Modules" in the left pane
  • select the relevant module in the centre pane
  • select the "Sources" tab in the right pane
  • find the folders mentioned above inside target and mark src_managed/main and twirl/main as "Sources" (note you mark the main folders, not the outer folders)

Cause 3: target is excluded

I have found that sometimes when you import a project, Intellij automatically marks the target dir as excluded. This means the "Sources" inside it are effectively ignored. So make sure that your auto-generated sources don't lie within some excluded directory.

To fix this follow the instructions in 2 and make sure that there are no special markings for the target folder. In my version of Intellij, that means the icon is a normal brown colour - not red or blue.

If you've had to do this, then it's possible that all the directories inside target are not excluded. For completeness sake, I'd recursively mark all the directories (like resolution-cache and streams) as excluded so that only the twirl and routes source directories are left not excluded.


We hit these problems a lot unfortunately as a team. One trick we use is to just copy/paste each other's .idea/modules/root.iml files as that's where all the config lives. So if one developer has a working setup, just copy over their Intellij conf to your own machine.

This is a snippet of my conf which relates to how sources and excludes are configured (it essentially replicates the steps in 2 and 3 above). I use it for a play 2.3 app and it works. You can try merging it into your root.iml if you have other complex config or dependencies which auto-generate code, or just replace your content element with this if you have a simple play project:

...
<content url="file://$MODULE_DIR$/../..">
  <sourceFolder url="file://$MODULE_DIR$/../../app" isTestSource="false" />
  <sourceFolder url="file://$MODULE_DIR$/../../app-2.11" isTestSource="false" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/src_managed/main" isTestSource="false" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/twirl/main" isTestSource="false" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/src_managed/test" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/twirl/test" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/../../test" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/../../test-2.11" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/../../conf" type="java-resource" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/resource_managed/main" type="java-resource" />
  <sourceFolder url="file://$MODULE_DIR$/../../target/scala-2.11/resource_managed/test" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/../../test/resources" type="java-test-resource" />
  <excludeFolder url="file://$MODULE_DIR$/../../target/resolution-cache" />
  <excludeFolder url="file://$MODULE_DIR$/../../target/streams" />
</content>
...
like image 31
rmin Avatar answered Oct 06 '22 17:10

rmin