直前期にそういうことするから
EclipseMEからEclipse本家に統合されたMTJに移行→publicでないクラスに対応してない+$を内部クラスとして処理
例:Test.javaからはTest.classとTest$*.classができると勝手に解釈
になってたせいでCUPの吐くpackage privateでしかもクラス名に$が入ってる気持ち悪いクラスのクラスファイルをJARに入れてくれず、NoClassDefFoundErrorという悲劇。これはひどい。オレはpackage privateなクラスも名前に$の入ったクラスも書いてないぞ・・・!
EclipseMEに戻すことも考えたけどparser.javaを解析(笑)してpackage privateなクラスをpublic classにして別ファイルにしちゃうコードをでっちあげました。これはひどい。$を_に直すため、ソースコードに特に意味のある$がないことを確認したのち、フル置換。これはひどい。
あとはAntでパーザジェネレートの後にこれをjava実行してやるだけです。二重にかけると壊れるので防止機能付き^^。
package tools; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; public class ParserFix { /** * @param args dir * @throws IOException */ public static void main(String[] args) throws IOException { if(args.length != 1){ System.err.println("Usage: ParserFix dir"); System.exit(1); } System.out.println("Parser Fix..."); String dir = args[0]; Scanner scanner = new Scanner(new File(dir + "/parser.java")); StringBuilder s1 = new StringBuilder(); StringBuilder s2 = new StringBuilder(); StringBuilder s3 = new StringBuilder(); int mode = 1; while(scanner.hasNextLine()){ String line = scanner.nextLine(); line = line.replace("class CUP$parser$actions", "public class CUP$parser$actions"); line = line.replace('$', '_'); if(mode == 1){ if(line.startsWith("/** CUP")){ mode = 2; } else{ s1.append(line); s1.append('\n'); } } if(mode == 2){ if(line.startsWith("/** Cup generated class to encapsulate user supplied action code.*/")){ mode = 3; } else{ s2.append(line); s2.append('\n'); } } if(mode == 3){ s3.append(line); s3.append('\n'); } } scanner.close(); if(s3.length() == 0){ System.out.println("Already fixed."); System.exit(0); } FileWriter out; out = new FileWriter(dir + "/parser.java"); out.write(s1.toString()); out.write(s2.toString()); out.close(); out = new FileWriter(dir + "/CUP_parser_actions.java"); out.write(s1.toString()); out.write(s3.toString()); out.close(); System.out.println("Fixed successfully."); } }