Все для той же цели, для которой я рисерчил ответ на вопрос, как компилить код java в рантайме я рисерчу ответы и на этот вопрос: как мне этот код еще и провалидировать. Чем можно валидировать? PMD, CheckStyle, FindBug, и т.д. - их очень много. Решил я начать с CheckStyle.
Качаем CheckStyle - нам нужен jar файл. Как описано тут, чекать свой класс на наличие всяких глюков надо так (из папки с jar)
Подключим к своему Maven проекту CheckStyle
Качаем CheckStyle - нам нужен jar файл. Как описано тут, чекать свой класс на наличие всяких глюков надо так (из папки с jar)
java -cp checkstyle-5.6-all.jar com.puppycrawl.tools.checkstyle.Main -c sun_checks.xml JavaClass.javaВ результате я увижу такое.
Starting audit... D:\checkstyle-5.6-src\bin\JavaClass.java:0: Missing package-info.java file. D:\checkstyle-5.6-src\bin\JavaClass.java:7: First sentence should end with a period. D:\checkstyle-5.6-src\bin\JavaClass.java:13:5: Missing a Javadoc comment. D:\checkstyle-5.6-src\bin\JavaClass.java:15:5: Missing a Javadoc comment. D:\checkstyle-5.6-src\bin\JavaClass.java:15:22: Parameter clazz should be final. D:\checkstyle-5.6-src\bin\JavaClass.java:15:28: 'clazz' hides a field. D:\checkstyle-5.6-src\bin\JavaClass.java:19:5: Method 'newInstance' is not designed for extension - needs to be abstract, final or empty. D:\checkstyle-5.6-src\bin\JavaClass.java:19:5: Missing a Javadoc comment. D:\checkstyle-5.6-src\bin\JavaClass.java:19:31: Parameter constructorArgs should be final. D:\checkstyle-5.6-src\bin\JavaClass.java:21: Line is longer than 80 characters (found 96). D:\checkstyle-5.6-src\bin\JavaClass.java:30: Line is longer than 80 characters (found 109). ... Audit done.Супер! Это уже что-то. Я теперь хоть знаю, где находится точка входа. Класс com.puppycrawl.tools.checkstyle.Main. А потому я открою исходники и посмотрю что там...
Подключим к своему Maven проекту CheckStyle
<dependency> <groupId>checkstyle</groupId> <artifactId>checkstyle</artifactId> <version>5.0</version> </dependency>После, по образу и подобию написанного в com.puppycrawl.tools.checkstyle.Main, напишем свой раннер
import com.puppycrawl.tools.checkstyle.ConfigurationLoader; import com.puppycrawl.tools.checkstyle.DefaultLogger; import com.puppycrawl.tools.checkstyle.PropertiesExpander; import com.puppycrawl.tools.checkstyle.api.AuditListener; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.api.Configuration; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.*; public class Checker { public List<String> checkstyle(String configFile, String javaFile) throws CheckstyleException { StringListOutputStream out = new StringListOutputStream(); AuditListener listener = new DefaultLogger(out, true); Configuration config = ConfigurationLoader.loadConfiguration(getPath(configFile), new PropertiesExpander(System.getProperties())); com.puppycrawl.tools.checkstyle.Checker checker = createChecker(config, listener); int numErrs = checker.process(Arrays.asList(new File(javaFile))); checker.destroy(); return out.getResult(); } private String getPath(String name) { return getClass().getClassLoader().getResource(name).getPath(); } private com.puppycrawl.tools.checkstyle.Checker createChecker(Configuration aConfig, AuditListener aNosy) { com.puppycrawl.tools.checkstyle.Checker c = null; try { c = new com.puppycrawl.tools.checkstyle.Checker(); final ClassLoader moduleClassLoader = com.puppycrawl.tools.checkstyle.Checker.class.getClassLoader(); c.setModuleClassLoader(moduleClassLoader); c.configure(aConfig); c.addListener(aNosy); } catch (final Exception e) { System.out.println("Unable to create Checker: " + e.getMessage()); e.printStackTrace(System.out); } return c; } } class StringListOutputStream extends ByteArrayOutputStream { public List<String> getResult() { return Arrays.asList(new String(toByteArray()).split("\\r\\n")); } }И воспользуемся им.
@Test public void test() throws CheckstyleException { String configFile = "sun_checks.xml"; String javaFile = "src/main/java/apofig/checker/Checker.java"; List<String> result = new Checker().checkFile(configFile, javaFile); assertEquals(19, result.size()); assertEquals("[Starting audit..., " + "D:\\CodeChecker\\src\\main\\java\\apofig\\checker\\Checker.java:0: Missing package-info.java file., " + "D:\\CodeChecker\\src\\main\\java\\apofig\\checker\\Checker.java:14: First sentence should end with a period., " + "D:\\CodeChecker\\src\\main\\java\\apofig\\checker\\Checker.java:21: Line is longer than 80 characters., " + "D:\\CodeChecker\\src\\main\\java\\apofig\\checker\\Checker.java:21:5: Method 'checkstyle' is not designed for extension - needs to be abstract, final or empty., " + ... "Audit done.]\n", result.toString()); }Дальше дело за настройкой конфига... Еще я сделал одну версию метода, который работает с классом но в строке. Дело в том, что checkstyle работает с файлами, а потому мне пришлось временно создать файл из строки и указать на него checkstyle.
@Test public void testCheckstyleText() throws CheckstyleException { String configFile = "sun_checks.xml"; String javaClass = "package apofig.checker;\n" + "\n" + "import java.io.ByteArrayOutputStream;\n" + "import java.util.Arrays;\n" + "import java.util.List;\n" + "\n" + "/**\n" + " * User: oleksandr.baglai\n" + " * Date: 1/19/13\n" + " * Time: 12:55 AM\n" + " */\n" + "public class StringListOutputStream extends ByteArrayOutputStream {\n" + "\n" + " public List<String> getResult() {\n" + " return Arrays.asList(new String(toByteArray()).split(\"\\\\r\\\\n\"));\n" + " }\n" + "\n" + "}"; List<String> result = new CheckstyleChecker().checkString(configFile, javaClass); assertEquals(7, result.size()); assertEquals("[Starting audit..., " + "class:0: File does not end with a newline., " + "class:0: Missing package-info.java file., " + "class:7: First sentence should end with a period., " + "class:14:5: Method 'getResult' is not designed for extension - needs to be abstract, final or empty., " + "class:14:5: Missing a Javadoc comment., " + "Audit done.]", result.toString()); }Вот исходники сырого проекта, если кому надо. Может пригодится...
Комментариев нет:
Отправить комментарий