はじめに
こんにちは。
今年から新卒でエンジニア & qiitaデビューした深澤です。
よろしくお願いします。
この前、PlayFrameworkを使った際、こんなエラーが出てきました。
routes.java:8: エラー: シンボルを見つけられません
おやおや、何かなこれは。
さらに、コンソールにはこんなエラー。
/target/scala-2.11/src_managed/main/contorllers/routes.java:8: エラー: シンボルを見つけられません
きついきついきついきつい
この手のエラー、実は結構経験していて、超単純な問題なのですが、あまり検索しても資料を見つけられなかった(僕の検索の仕方が悪いのかもしれませんが・・・)ので、今回まとめてみました。
Playに詳しい方にとっては、どうってことない問題かもしれませんが、
少しでも誰かの参考になれたら幸いです。
間違いやご質問などあれば、お気軽にコメントください。
環境はMacOSとPlayFramework2.3.8(java)です。
そもそもplayのtargetってなんや
これは本家のサイトを参考にさせていただきました。
https://www.playframework.com/documentation/ja/2.3.x/Anatomy
こんな具合に書かれています。
target/ ディレクトリには、Play のビルドシステムによって生成された全てのファイルが入ります。何が生成されるのか覚えておくと良いでしょう。
classes/ には、Java や Scala のコードからコンパイルされたクラスファイルが入ります。
classes_managed/ には、Play が管理しているクラス (例えば、ルータやテンプレートシステムによって生成されたクラスなど) が入ります。IDE をお使いの場合は、このディレクトリへクラスパスを通しておくと便利でしょう。
resource_managed/ には、Play によって生成されたリソースが含まれます。例えば、LESS CSS や CoffeeScript からトランスコンパイルされた CSS ファイル や JavaScript ファイルは、このディレクトリに配置されます。
src_managed/ には、テンプレートシステムが生成した Scala コードなど、Play によって生成されたソースが含まれます。
web/ には、app/assets と public とフォルダから sbt-web によって生成されたアセットが含まれます。
ここまでがっつり日本語資料あるとありがたいですね。
わかりやすい。
playでコンパイルかけた際、いわゆる中間ファイルが入るディレクトリみたいです。
だから、コンパイルの際、こんな感じのログが出るんですね。
[info] Compiling 2 Scala sources to AppName and path/target/scala-2.11/classes...
今回の僕のケースでは、src_managedの部分です。
原因は?
結論から言うと、なんらかの原因で生成された間違った中間ファイルを、実際にアプリケーションを動かした際に参照してしまい、playが「見つからないよ!」って言ってるのが原因です。
間違った中間ファイルは、例えば、コントローラのどっかで、
「controllers」と書かなければならないのに
「contrllers」としてしまったりして、その状態でコンパイルしたりするとこうなります(笑)
コンパイルは普通に通るのですが、いざ、runningしたりしてアプリケーションを動的に起動すると、定義されたアクションを見つけられなくなります。
実際に自分のエラーが発生しているtargetディレクトリを参照してみると、こんな感じになってました。
$ ll
total 48
drwxr-xr-x 6 staff 204 4 14 22:12 .
drwxr-xr-x 3 staff 102 4 1 21:30 ..
drwxr-xr-x 3 staff 102 4 15 01:09 contorllers
drwxr-xr-x 3 staff 102 4 1 21:30 controllers
-rw-r--r-- 1 staff 11137 4 14 22:14 routes_reverseRouting.scala
-rw-r--r-- 1 staff 10504 4 14 22:14 routes_routing.scala
コントローラの中間ファイルが二つも生成されている・・・。
きっと、コントローラの定義を間違えて、contorllersにしてしまったんですね・・・。
routes.javaくんも一生懸命インスタンスを作ろうとしてくれてますが、これでは何も生成できるわけがありません。
package contorllers;
public class routes {
public static final contorllers.ReverseUsers Users = new contorllers.ReverseUsers();public static class javascript {
public static final contorllers.javascript.ReverseUsers Users = new contorllers.javascript.ReverseUsers();
}public static class ref {
public static final contorllers.ref.ReverseUsers Users = new contorllers.ref.ReverseUsers();
}}
パッケージ名から間違ってしまっています。
じゃあ、どーしたら良いの??
その間違っている部分を全て修正すれば良いのですが、状況によっては、量が膨大すぎてやってられない場合もあります。
今回のようなケースなら、単純に、誤って参照されているほうのディレクトリを消し去るのも一つの手段です。
$ sudo rm -r contorllers/
また、playにはいわゆる中間ファイルを全てクリアするコマンドが用意されているので、それを利用するのも手でしょう。
次のようなコマンドが用意されてます。
$ activator clean
$ activator clean-files
これで無事に動くようになるはずです。
以上です!
初qiitaの記事ですごく緊張しました。
お気軽にレビュー御願いします。
最後までありがとうございました。