0

Consider the common problem of adding tracing to your code. Suppose AspectJ or Spring AOP approach is NOT something you want to do - what other approaches are possible, besides simply adding the traces manually?

Supposedly Spoon or JavaParser are alternatives, any examples are welcome.

Tried AspectJ, it works very well but then its Maven plugin is poorly supported - trying to get to the commit team to fix it for Java 9+. Also, we don't know how long AspectJ will be supported, given the current Java release pace.

aleksander_si
  • 1,021
  • 10
  • 28
  • https://github.com/SpoonLabs/spoon-maven-plugin https://github.com/SpoonLabs/spoon-examples/blob/master/src/main/java/fr/inria/gforge/spoon/transformation/autologging/LogProcessor.java – aleksander_si Sep 11 '19 at 09:18

1 Answers1

1

It is possible to do it with Spoon. Here is a code snippet that adds a System.out.println with the name of the method as a first instruction to every method in a class TheClass whose source code is located in ./project/src. The generated code will be stored in ./project/generated.

 Launcher launcher = new Launcher();
 launcher.addInputResource("./project/src/");

 launcher.buildModel();

 CtModel model = launcher.getModel();

 List<CtType> filteredTypes = model.getElements(
                (CtType type) -> type.getSimpleName().equals("TheClass"));

 CtType functionsClass = filteredTypes.get(0);
 Factory factory = launcher.getFactory();
 for(CtMethod method : (Set<CtMethod<?>>)functionsClass.getMethods()) {
    method.getBody().insertBegin(
          factory.createCodeSnippetStatement(
           "System.out.println(\"" + method.getSimpleName() +  "\")"
    ));
 }

JavaOutputProcessor processor = new JavaOutputProcessor(
     new File("./project/generated"), launcher.createPrettyPrinter());
processor.setFactory(factory);
processor.createJavaFile(functionsClass);

You may also consider to use Javassist if you can target the compiled bytecode. See examples here https://www.javassist.org/tutorial/tutorial.html

Here are some examples of both, Spoon and Javassist, that you may find helpful https://github.com/Software-Testing/code-manipulation

  • Hello Oscar, thanks for your post. I have read that Spoon requires the entire class path of the "import" statements to be able to process code - do you know anything about this? Does the same also apply for imports of imports - the entire dependency tree? – aleksander_si Sep 26 '19 at 11:19
  • 1
    Hello @aleksander_si, yes, it is better to provide the full classpath. However, I believe Spoon can process code files without all the classpath elements, just not all the information will be available. It depends on what you want to do. Take into accoun that, if you want to target a Maven project, the MavenLauncher class is able to compute the required classpath. – Oscar Luis Vera Perez Sep 27 '19 at 12:53