Code generation in Maven - java

I want to autogenerate some java classes from interfaces. My first thought was to write a code generator, and integrate it as a maven plugin.
I was thinking of creating a maven plugin with a codegen goal that is called during the build process.
So if I choose this route, how do I provide the plugin with the interfaces to be processed? And where should the generated files go?
Are there any existing plugins that can be configured to generate default class implementations?

Sources should go in {project.build.directory}/generated-sources/[plugin-id]/
Most plugins take configuration passed through the plugin configuration section in the pom. You can use default values as well, or an annotation and classpath scanning.
A plugin like the maven-jspc-plugin generates code, which you could take a look at. The "Better Builds With Maven" e-book also contains a reasonably comprehensive chapter on writing plugins.

Maybe have a look at the XDoclet Maven plugin- XDoclet is often used for generating sources from doclet-style markup in classes (e.g. autogenerating MBean interfaces from implementations) and that sounds similar to what you're doing.

I have used APT-Jelly to successfully generate java source code from annotated java. You may want to check it out.

Related

How to change the location of classes generated by MapStruct?

I am using MapStruct to generate the mapping between the JAXB classes and my domain classes.
I am using gradle plugin as described in MapStruct official site. During the compilation process, the classes are generated in "build/generated/sources/apt/main".
How can i change this location? I am not able to find any guide for gradle though there is a compiler flag to change it through ant script, but unfortunately it is not working for gradle
Any help is appreciated.
This is not linked to MapStruct, but to the way the gradle apt plugin works and how it tells the Java compiler to place the generated sources.
To configure the generated sources of the plugin according to the configuration documentation. One needs to extend the aptOptions of the compile. The property controlling the destination of the generated is generatedSourcesDestinationDir

Is there anything like pkg-config for Java?

I have a project where our CLASSPATH is getting out of hand. We have jars that depend on other jars, which in turn depend on even more jars, as well as a large collection of third-party jars. So each time we use one of these jars we need to construct a rather large CLASSPATH, and if downstream dependencies change it is no longer in sync.
One thought is to maybe write a tool a little like pkg-config to help with all of this. I did some searching and didn't find anything. Are there any tools like this that I've missed or do people have alternate solutions?
No, I don't want to use Maven. We already have a different build system in place.
If you aren't already using a build tool, I recommend starting with Maven. The main thing that turns people off Maven is that it has a standard project structure. Personally, I think that's a good thing.
If you want to be a little more free-form with your projects, there are the Maven Ant Tasks for Ant. I much prefer these to Ivy, but part of that is because I'm used to the Maven artifact naming conventions.
In either case (or if you use Ivy), look into a repository manager. Nexus is written by the people who maintain Maven, and I find it easier to use than Artifactory, which is another widely used system. One benefit for Artifactory is that they provide hosting (for a fee).
You may want to use maven with an IDE plugin like m2eclipse. All you have to do is type the class in your code and it will help you search for and bring in the right packages with their dependancies. It will also automatically configure the classpath for you. Here is a quick tutorial http://www.sonatype.com/people/2010/03/adding-dependencies-using-m2eclipse/

Share entities between multi-projects

I have 3 Java projects with the same entities.
I want to share entities between these projects because entities can evolve during the development phase.
We are thinking about building a jar with entities and sharing it using Maven (with a repository).
Maybe you have another solution ?
I also can recommend to use Maven to share code between projects.
Here are some tips to get started:
Use a Maven Repository Manager such as Nexus. It will help you to
create a stable development environment.
Every developer (also the Continuous Integration Server user) should configure their settings file to use your Maven Repository
Manager. Don't specify your repositories in the POMs, confiugre them
only in your Maven Repository Manager.
http://www.sonatype.com/books/nexus-book/reference/maven-sect-single-group.html
Use the dependencyManagement and pluginManagement elements of your parent POMs to specify all versions of the plugins and dependencies
you are using. Omit these versions in the other POMs (they will
inherit them from the parent POM).
I also recommend to use different POMs for multi-module builds and parent POMs.
If you want to share common interfaces, classes, functionality or components, Maven is the way to go. In addition to the dependency management, you also get the added bonus of a standard project layout that will simplify things. Easy integration with most common continuous integration servers and a standard release process are further benefits.
Definitely take a look at Maven!
making an own JAR-library is definitely a good solution.
The jar-file is easy to distribute via dependency management (maven, ivy, gradle ..)
The jar is versioned
The projects using the library can be tested against a certain verion. Otherwise it may gets a problem if you change enties and forget to change a depending project. -> integration tests
Regards
Entities are the representation of a given object am I correct? If so the default mechanism implemented by Java is Object serialization - http://en.wikipedia.org/wiki/Serialization. In the case of jar files if an entity changes you would have to change jar once again each time as well. It may be tedious.
Geneate a standard war file in roo.. But then change it's package to jar file.
Then from any standard war file you can just deploy this jar (Ill use the jar as a maven dependency). Ill maintain a unique named applicationConext like pizzaShop-applicationContext.xml and like pizzaShop-applicationContext-jpa.xml. so from a parent spring project I can stack up various roo projects in this fashion.
Ill also keep their generated webapps folder to allow for the generator to work more easily. (This means I have to open up the pom.xml and keep changing it back to jar). Also helps with cut and paste fodder for non roo generated war files web.xml entry additions.
Seems like it may be a confusing point about roo.. You can just mix and match these jars as you would any spring project. They function like self contained units of springness and work fine sitting side by side with other spring jars all under the same webapp/web.xml context.
Its tedious but still better then writing spring code by hand.

Maven replacement?

What would you suggest as a replacement to the Maven Java build toolset? Just plain Ant scripts? SCons?
It depends on what you use anyway. Maven 1? Maven 2? I find Maven 2 decently documented, and quite powerful, when used in combination with Ant tasks and some home baked Java plugins.
There are Ant tasks to use Maven features from Ant: http://maven.apache.org/ant-tasks/index.html . So you don't really need to write your own "library".
And you can call Ant from Maven: http://maven.apache.org/plugins/maven-antrun-plugin/ .
You can also script things using Groovy for example: http://groovy.codehaus.org/GMaven+-+Executing+Groovy+Code .
Or just write Java code for the custom bits you need: http://maven.apache.org/guides/plugin/guide-java-plugin-development.html .
There's no reason not to mix and match, when you can do it ;)
While I like the idea of Maven, I always find myself fighting it for anything but the simplest configurations. Its architecture is plugin-based, and the quality of the plugins varies widely. Documentation is sketchy at best; half the time I can't figure out if the doc I'm reading is for Maven 1 or 2. And how often have you had to resort to using the maven-ant-plugin to do something basic?
I've been using Apache Ivy for about a year now, and I'm pretty happy with it. There is a bit of a learning curve though. But there's an active mailing list, and the author is very responsive.
What I ended up doing was writing a "library" of a few simple Ant targets such as "resolve", "compile", "install", etc. that expect things to be in standard Maven places (such as src/main/java) and then <import> the targets into my various projects. This way you get the best of both worlds- Maven-style configuration, and all the power of Ant.
I'm fond of using Ant with Ivy. Ivy uses Maven repositories to fetch library dependencies without forcing you to change your entire build system to suit Maven.
I've been using buildr for some of my projects. Very terse and readable build scripts (no xml) and it uses maven repos (with trivial effort, maven 1 and maven 2).
I was looking for something post-maven1 to work on for some projects and m2 wasn't all that appealing. Maven had already left all m1 users high and dry with the need to redo all of their build systems (and some of mine cannot be expressed in m2 as far as I can tell).
I really like using ant4eclipse - you set up your project dependencies in eclipse as normal and you can write a single ant script that'll build all the projects in the right order.
For third-party libs, you can either set up a single eclipse project containing (and exporting) all of your jars [I DON'T RECOMMEND THIS], or a separate project for each third-party lib, exporting the jar. [I recommend the latter b/c you can track project->third-party deps and upgrade parts when needed.]
I would go with buildr, if i am expecting complex build targets in my build. The benefit is, you are not dependent on any particular library at all. You have all the APIs from Ruby to do whatever you want; unlike Ivy in which case you are still tied up to ANT. Effort of migration to Ivy is worth if you want to introduce library dependency to an already established ANT based build mechanism which does all the operations you want to do.
There are at least three different parts of Maven: the repository, the implementation independent lifecyle and the conventions for a default project. Using Ivy provides only the repository.
I've not used it but I think that easyant is designed to be a more complete replacement to Maven. It uses Ivy as the repository but then adds conventions and standard modules.

Restrict dependencies between Java packages

What are the possibilities to enforce restrictions on the package dependencies in a Java build system? For example, the myapp.server.bl.Customer class should not be allowed to refer to the myapp.client.ui.customlayout package.
I'm interested in either Ant-based or IDE-specific solutions.
I'd like to get an error message in the build indicating that a (custom) package dependency rule has been violated and the build aborted. I also would like to maintain the dependencies in a list, preferably in a text file, outside of the Ant scripts or IDE project files.
(I don't know Maven but I've read it here it has better support for module dependency management)
I believe Checkstyle has a check for that.
It's called Import Control
You can configure Eclipse projects to specify Access Rules. Access rules can specify "Forbidden", "Discouraged", and "Accessible" levels all with wildcard rules. You can then configure violations of either Discouraged or Forbidden to be flagged as either warnings or errors during builds.
Kind of an old article on the idea (details may be out of date):
http://www.eclipsezone.com/eclipse/forums/t53736.html
If you're using Eclipse (or OSGi) plugins, then the "public" parts of the plugin/module are explicitly defined and this is part of the model.
ivy seems like a good solution for your problem (if you are using ant). Ivy is the offical dependency management component of Ant and thus integrates nicely with ant. It is capable of resolving dependencies, handle conflicts, create exclusions and so on.
It uses a simple xml structure to describe the dependencies and is easier to use than Maven, because it only tries to address dependency resolution problems.
From the Ivy homepage:
Ivy is a tool for managing (recording, tracking, resolving and reporting) project dependencies. It is characterized by the following:
flexibility and configurability - Ivy is essentially process agnostic and is not tied to any methodology or structure. Instead it provides the necessary flexibility and configurability to be adapted to a broad range of dependency management and build processes.
tight integration with Apache Ant - while available as a standalone tool, Ivy works particularly well with Apache Ant providing a number of powerful Ant tasks ranging from dependency resolution to dependency reporting and publication.
For the IDE specific solutions, IntelliJ IDEA has a dependency analysis tool that allows one to define invalid dependencies as well.
http://www.jetbrains.com/idea/webhelp2/dependency-validation-dialog.html
The dependency violation will be shown both when compiling and live, while editing the dependent class (as error/warning stripes in the right side error bar).
Even more automation can be obtained with JetBrains' TeamCity build server, that can run inspection builds and report the above configured checks.
For another IDE independent solution, AspectJ can be used to declare invalid dependencies (and integrate the step in the build process, in order to obtain warning/error info for the issues).
Eclipse has support for this via Build Path properties / jar properties. I think it may only work across jar / project boundaries.
Maybe Classsycle can be used:
http://classycle.sourceforge.net/ddf.html
You can use multiple modules in IDEA or Maven or multiple projects in Eclipse and Gradle. The concept is the same in all cases.
A trivial interpretation would be a module for myapp.server.bl and another for myapp.client.ui.customlayout with no compile time dependencies between either of them. Now any attempt to compile code or code-complete against the opposite module/project will fail as desired.
To audit how extensive the problem already is, a useful starting point for IntelliJ IDEA is Analyzing Dependencies:
http://www.jetbrains.com/idea/webhelp/analyzing-dependencies.html
From that article you can see how to run and act on dependency analysis for your project.

Categories

Resources