I started to look at the existing versions, most of them were either using jde or jikes or both. I do not like jde, it does too much and since jikes is no good for java/6 wich is all I code nowdays I started working on my own version of flymake/ecj.
One of the first things that I noticed was that the compilation process used in standard flymake is:
I selected ecj, the eclipse compiler for a few reasons, easier api and more warnings are the two big reasons.
Get the compiler java compiler binary and unpack it. It includes the tiny source code as well so if you want to modify it you can easily do so.
Add the needed lines to your .emacs to start using flymake:
(add-to-list 'load-path "~/pkg/flymake/cvs") (require 'flymake) ;(setq flymake-log-level 2) ; set this when debugging flymake (setq flymake-compiler-jar "/home/robo/src/java/ecj-flymake/jars/compiler.jar")I also prefer to change a few simple things:
(global-set-key [f4] 'flymake-display-err-menu-for-current-line) (global-set-key [f3] 'flymake-goto-next-error) (custom-set-faces '(flymake-errline ((((class color)) (:underline "Red")))) '(flymake-warnline ((((class color)) (:underline "Orange")))))If you work on larger projects it can also be nice to turn off recompilation on newline:
(setq flymake-start-syntax-check-on-newline nil)You can also increase the time for recompiles after changes:
(setq flymake-no-changes-timeout 10)The projects I work on are usually laid out a bit differently, so to get flymake to handle the different directory layouts we need to tell flymake where the different sources, classes and external libs can be found. You can also change the flags to ecj here if you want.
(defun compile-server-dir-init (base-dir src-dir lib-dir) (let* ((temp-file (flymake-init-create-temp-buffer-copy 'java-ecj-create-temp-file)) (jar-files (files-in-below-directory-safe base-dir lib-dir)) (class-path (mapconcat 'identity jar-files ":")) (command (format (concat "-Xemacs -1.6 -proceedOnError -proc:none " "-warn:-serial -warn:+uselessTypeCheck,unnecessaryElse -warn:+over-ann " "-sourcepath %s %s %s\n") (get-source-dir base-dir src-dir) (get-class-path-string class-path) temp-file))) (list command))) (defun compile-server-rabbit-init () (compile-server-dir-init "/home/robo/src/java/RabbIT3/" "src" "external_libs")) (push '("/home/robo/src/java/RabbIT3/src.+\\.java$" compile-server-rabbit-init compile-server-flymake-cleanup) flymake-allowed-file-name-masks)Now we also tell emacs to start flymake when entering java mode:
(push '("\\(.*?\\):\\([0-9]+\\): error: \\(.*?\\)\n" 1 2 nil 2 3 (6 compilation-error-face)) compilation-error-regexp-alist) (add-hook 'java-mode-hook 'flymake-mode-on)You can find my .emacs here for more examples.