Visual Studio Code doesn't follow maven goal - java

I'm working with a Java project and Visual Studio Code as a IDE. This project make use of ActiveJDBC. ActiveJDBC requires instrumentation of class files after they are compiled. Usually this is done with a maven plugin that start in the process-classes phase.
<plugin>
<groupId>org.javalite</groupId>
<artifactId>activejdbc-instrumentation</artifactId>
<version>${activejdbc.version}</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
</executions>
</plugin>
My workflow with VSC is simply to change the source code and run/debug/test the project. As far as I know VSC compile the java files every time I save, but doesn't follow the maven rules and so, it didn't run the instrumentation process.
I would like to press F5 (debug the project) without having to remeber to call the instrumentation if a modify some class of the model. Any suggestion?

Related

Java Documentation from Vscode

Hey I am using the Spring tool suite for Vscode It's working great but there is one thing I am missing like in other IDE's you can view the documentation for a specific Annotation or method.
for example:
If I try to view the documentation for any annotation in intellij it shows the documentation properly, but if i try to do the same on vscode it shows up like this:
You can enable the setting java.maven.downloadSources.
Then each time you opened a class file, if the source jar does not exist locally, the extension will trigger a download task for that source jar. After that, next time you open that class file, you can see the source.
This message says that VS Code couldn't find the JAR archive that contains source files for this class. These JARs usually are called XYZ-sources.jar. You need to download an archive like that manually or use the Maven plugin that can download it for you.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>src-dependencies</id>
<phase>package</phase>
<goals>
<goal>sources</goal>
</goals>
<configuration>
<silent>true</silent>
</configuration>
</execution>
</executions>
</plugin>
Then, if you have downloaded JAR archive you need to press Right Mouse Button -> Attach Source.

Customized build lifecycle for Java project

Working on one Maven project, I faced quite a curious kind of dependencies cycle: there are two maven modules, one of which is instrumenting the Java bytecode, and at the same time uses assertions (for unit-testing purposes), defined in another module, which is in turn supposed to be instrumented by the first one.
So, it's not just a cycle, it's cycle, spreaded between maven phases. I failed to solve it by means of reorganizing Maven modules, and I doubt that it is possible in such case.
Hypothetical solution for this problem might be to reorganise build lifecycle in a following way:
Compile the first module's sources
Compile the second module's sources
Instrument the second module using the 1st module's classes
Test first and second modules
Package them
Install/deploy them
I doubt that Maven was designed for such hacks. What about other tools? Can it be done with Gradle or Ivy? Or maybe it is possible in Maven by some plugin? Or probably the problem is typical and has more straight solution?
PS: please do not suggest to outline common dependencies to a separate module. If it was so simple, I wouldn't be here.
In my opinion you should look on Gradle for this task, specifically to it's multi-project builds. Gradle allows to access tasks from any project of multi-project build from any build script. Therefore, you should define tasks you need in subprojects and call them from the root project in any order you want.
Gradle proposal was really good, but was not applicable in my case due to internal obstacles.
For Maven, I just had to admit that separating the instrumentation code and test assertions to modules is not possible in my case: they are too coupled at build time. So, instead of trying to separate them at build time, I managed to separate them afterwards.
Note that this solution is not nice way of doing stuff: you may get class loading exceptions at runtime if the classes you are trying to separate are actually using each other. Also, there won't be any transitive resolution between the separated jars - Maven will treat them as completely independent.
So, I managed to get instrumentation code and test assertions separated to two jar artifacts by following this step sequence:
Let them both be in one Maven module.
Do compilation and instrumentation on the module's build phase and testing on test phase as usual. It is no more the problem since all the nesessary stuff for this phases is located right in the module.
At package phase, configure maven jar plugin to collect additional artifacts with limited set of class files.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>jar-api</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>api</classifier>
<includes>
<include>com/example/api/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>jar-codegen</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>codegen</classifier>
<skipIfEmpty>false</skipIfEmpty>
<includes>
<include>oo/example/codegen/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>jar-tests</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<skipIfEmpty>false</skipIfEmpty>
<classifier>tests</classifier>
<includes>
<include>com/example/tests/**</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
At install phase, these additional artifacts will be installed to local repository together with the assembled module.

Issue setting the class path in Maven exec plugin when running a Main Class

I have embedded Jetty in my application. In order to automatically execute my integration tests on my build server I'd like Maven to start my application in the pre-integration-test phase. The integration tests are in another project than the application te be tested, because the tests are of a quite complex nature and should be seperated from production code.
I have tried to set up my application using the Maven exec plugin, but keep running into ClassNotFoundErrors. I use the maven-dependency-plugin to copy all dependencies to target/lib/. Until now, I haven't been able to figure out how to tell the exec plugin to add that lib folder to the class path.
This is my current exec plugin configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>default-cli</id>
<phase>pre-integration-test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.zertificon.managementCenter.adminUi.server.WebApp</mainClass>
<!-- this does not work: -->
<classpath>${project.build.directory}/${libFolder}/</classpath>
</configuration>
</execution>
</executions>
</plugin>
The WebApp class I am trying to run originates from another Project and is installed in the local repository. I would highly apreciate any help.
Found the error: I have been using Jetty together with a Selenium Library that itself bundles Jetty, too. This lead to a wrong Jetty Version being loaded wich gave me class not found errors. Go figure.

Running caliper from eclipse in maven's test scope

I have a Java project in Eclipse, with JUnit tests in my src/test directory. I've also added a class to my tests with Caliper microbenchmarks, and I'd like to be able to run these tests from within Eclipse.
As the Caliper code is test code, I've added Caliper as a dependency in Maven in test scope. That makes it show up in the classpath when I run JUnit tests, but I can't see a way to run an arbitrary class with test dependencies in the classpath. What I tried doing was adding a new Run Configuration for a Java Application, thinking I could launch CaliperMain with the right class as a parameter, but the Caliper jar is not on the classpath and I can't see how to add it.
I don't want to move my benchmark code and dependency into the main scope, as it's test code! It seems seriously overkill to move it into a completely separate project.
You should be able to do this with the Maven Exec Plugin. For my project, I opted to make a benchmark profile that can be run with the maven command mvn compile -P benchmarks.
To configure something like this, you can add something along the lines of the following to your pom.xml, specifying scope of the classpath as test using the <classpathScope> tag:
<profiles>
<profile>
<id>benchmarks</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>caliper</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>com.google.caliper.runner.CaliperMain</mainClass>
<commandlineArgs>com.stackoverflow.BencharkClass,com.stackoverflow.AnotherBenchmark</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Alternatively, if you'd like to specify a lot of options for caliper, it is probably easier to use the <arguments> tags:
<executions>
<execution>
<id>caliper</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>com.google.caliper.runner.CaliperMain</mainClass>
<arguments>
<argument>com.stackoverflow.BencharkClass</argument>
<argument>--instrument</argument>
<argument>runtime</argument>
<argument>-Cinstrument.allocation.options.trackAllocations=false</argument>
</arguments>
</configuration>
</execution>
</executions>
More configuration options (like -Cinstrument.allocation.options.trackAllocations above) can be found here and more runtime options (like --instrument above) can be found here.
Then, if you are using the Eclipse m2 Maven plugin, you can right-click on your project folder and select Run as... -> Maven Build... and enter something like clean install in the Goals input box and benchmarks in the Profiles input box and click Run and you should see the output in your Eclipse console.
It's important to note that I used a local snapshot build of Caliper by checking out the source using git clone https://code.google.com/p/caliper/, which is recommended at the time of this post in order to take advantage of the latest API.

How to use Maven classpath to run Java main class?

I'm currently using Maven to build my Rhino JavaScript project, download dependent libraries, and manage the classpath at runtime. I'm able to run the JavaScript entry point by using the Maven exec plugin, in the following way:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.mozilla.javascript.tools.shell.Main</mainClass>
<classpathScope>runtime</classpathScope>
<arguments>
<argument>path/to/entryPoint.js</argument>
</arguments>
</configuration>
</plugin>
This works well, but the problem is that maven takes about 10 seconds just to start, which is about 10 times longer than it takes my program to run. Is there a way to either:
improve the performance of the maven exec plugin so that it takes less time to start, or
export the classpath that maven would use at runtime, so that I can just start my program from a script?
You can use the -o / --offline switch to tell Maven to not bother checking for snapshot or plugin updates.
Use the appassembler or assembly plugins to generate startup scripts which will automatically (in the case of appassembler) reference the desired classpath.

Categories

Resources