Gradle: use of java pluggin classes task - gradle

Gradle java plugin offers a classes task, which describes
"Assembles the production classes and resources directories."
what does it mean? what exactly it does.
One more task is check, it says
All verification tasks in the project, including test.
what does this means? what are the other verification tasks apart from test?

Assembles the production classes and resources directories
It assembles under your build directory both class-files and resources, in the classes and resources folders accordingly. It depend on the comlipe and processResources tasks and make both of them run. That mean, that you can get the content, in your build folder, which later will be added into some archive (jar, war or ear) if you'll call some task to assemble it.
what are the other verification tasks apart from test?
You can add some plugins to your build script, for example checkstyle or findbugs. This plugins add some additional verifications, such a static analysis of source code and etc. All this actions will be performed while check is executed.

Related

adding other modules in classpath for a Gradle plugin task

I have a Gradle plugin that works well so far, however, I am facing an issue in a multi-module project.
The plugin runs its task in every module of the project, but sometimes, I need to access classes from other modules to analyze them - typically, in the context of hexagonal architecture, I want to perform some checks on classes in infrastructure that implement an interface defined in domain module.
So, when the task runs (after the tests) within infrastructure module, it finds the class. But it's not able to load the interface (from domain) that the class implements. When I do :
Object interfaceLoadedDynamically = Class.forName(i.getName());
I clearly see it can't be loaded, and that prevents me from performing the checks I need to do.
here are :
the plugin
the task
Is there a way to configure one of them to say : "when you run within a module, make sure all the other project modules that have been compiled before are available in the classpath" ?
I've seen maybe I could use Gradle's Configuration , but I am really not sure where/how to start.

Extend JavaExec task with additional configuration on the classpath

I have a task of type JavaExec that does a lot of complicated steps in order to compile & run the application. This task is generated by a plugin outside of my control.
I want to create another task that "extends" this task, adding an extra dependency configuration. This configuration stores some dependencies that should only be included for this specific task.
Is there an easy way for me to create such a task, or do I have to copy over all configuration properties (which may change at any time) manually?

How to test gradle code from build.gradle

There is more and more gradle code in my build.gradle.
The question is how to test gradle code from build.gradle. Is there any convention?
I'm not sure if this is convention but what You need to do is to make use of gradle tooling API. Basically it enables to You to load a build.gradle file, execute various tasks and verify the output. This code may be written as a normal test classes. You can find examples of such testing here and here for instance. Tests are written in spock.
Usually, code in build.gradle isn't tested. Instead, reusable/generic parts of the code are factored out into plugins and tasks implemented as classes, which are more amenable to testing.
A potential alternative is to test a task A by adding a task testA that depends on A and checks the outcome of A.

Understanding Maven scoping better

I have been struggling to figure out what's the use of scoping that is provided by Maven
as mentioned here.
Why should you not always have compile time scoping? Real life examples would be really appreciated.
The compile scoped dependencies are only used during compilation.
The test scoped ones -- only during tests. Say you have tests using junit, or easymock. You obviously do not want your final artifact to have a dependency on them, but would like to be able to just depend on these libraries while running your tests.
Those dependencies which are marked provided are expected to be on your classpath when you're running the produced artifact. For example: you have a webapp and you have a dependency on the servlet library. Obviously, you should not package it inside your WAR file, as the webapp container will already have it and a conflict may occur.
One of the reasons to have different scopes for dependencies is that different parts of the build can depend on different dependencies. For example, if you are only compiling your code and not executing any tests, then there is no point in having Maven downloading your test dependencies (if they're not already present in your local repository, of course). The other reason is that not all dependencies need to be placed in your final artifact (whether it's an assembly, or WAR file), as some of the dependencies are only used during the build and testing phases.
compile
Will copy these jar files into prepared War file.
Ex: hibernate-core.jar need to have in our prepared War.
provided
These jars will be considered only at complie time and test time
Ex:
servlet.jar will be provided by deployed server, so no need to provide from our prepared War file.
test
These jars are only required for running test classes.
Ex: Junit.jar will be required only for running Junit test classes, no need to deploy these.
Scopes are quite well explained in here:
https://maven.apache.org/pom.html#Dependencies
As a reference, I copied the paragraph:
scope: This element refers to the classpath of the task at hand
(compiling and runtime, testing, etc.) as well as how to limit the
transitivity of a dependency. There are five scopes available:
compile
- this is the default scope, used if none is specified. Compile dependencies are available in all classpaths. Furthermore, those
dependencies are propagated to dependent projects.
provided - this is
much like compile, but indicates you expect the JDK or a container to
provide it at runtime. It is only available on the compilation and
test classpath, and is not transitive.
runtime - this scope indicates
that the dependency is not required for compilation, but is for
execution. It is in the runtime and test classpaths, but not the
compile classpath.
test - this scope indicates that the dependency is
not required for normal use of the application, and is only available
for the test compilation and execution phases.
system - this scope is
similar to provided except that you have to provide the JAR which
contains it explicitly. The artifact is always available and is not
looked up in a repository.
there are a couple of reasons that you might not want to have all dependencies to be default compile scope
reduce the size of final artifact(jar,war...) by indicating different scope.
when you have a multiple-modules project, you have ability to let each module have it's own version of dependency
avoid class version collision by provided scope, for instance if you are going deploy a war file to weblogic server, you need to get rid of some javax jars, like javax.servlet, javax.xml.parsers, JPA jars and etc. otherwise you might end up with class collision error.

How to run tests after deployment using Maven?

I'm trying to decide how to create a set of Acceptance Tests for a Java-EE web application.
Here's the setup: Maven is used to generate a WAR file and deploy it into Glassfish. On deployment, the MySQL database schema is automatically updated from model classes using Hibernate ("hbm2ddl=auto" option).
The Acceptance Tests need to test the deployed code by invoking various methods and checking the results are as expected(*). We wrote an additional set of packages to hook into an existing system so the Acceptance Tests should show how these can be integrated into the existing codebase.
(*) This may sound more like Unit/Integration Testing but they are Acceptance Tests in the sense that they should prove what we did works and they need to be run after deployment so there is a database in place.
From the above, my current thinking is to use JUnit to check expected values etc. The bit I'm struggling with is how to invoke these tests after deployment. "deploy" is Maven's last phase so not sure if this is possible?
Just because that phase is called deploy doesn't mean that you have to use it for deploying your application for testing. In fact, it should only be used for "deploying" the artifact to a maven repository. Read through the description of the Maven lifecycle phases and you'll see that there are some phases dedicated to your use case:
pre-integration-test
integration-test
post-integration-test
Have a look at the Cargo Maven plugin. It's made to deploy your WAR file to various containers for testing. They definitely show demos of use cases like the one you describe on your site. I would expect that ultimately, you can be using Cargo to deploy to your container ( from one of the earlier phases like pre-integration-test )
Note, Jenkins also has a plugin that is a wrapper around the Cargo plugin. So you might do what you need via Jenkins. Also note, you don't need to run your Jenkins build job as mvn clean deploy. You could have one build job that just runs the integration tests, and fires another "deploy" job only when it succeeds.
If you really need to do stuff after deployment, then you can either run failsafe, and by implication JUnit) as part of the deploy phase.
What I usually do, if to have seperate module. So, you can have one maven project, which contains your project and a separate 'deployment test' project. Then, building the parent project will build and run your war and then run the deployment tests. You can use junit as normal.
The second fits better into jenkins because you'll still have a single project as well.

Resources