I'm developing a Maven plugin that will have provide 5 goals. You can either execute goals 1-4 individually, or execute goal5, which will execute goals 1-4 in sequence. I've been looking for a way to reuse (i.e. invoke) one Maven goal from within another, but haven't found it yet.
Of course, I could just have goalX delegate to ClassX for most of it's functionality, then when goal5 is invoked, it delegates to Class1...Class4, but this still involves a certain amount of code duplication in terms of specifying, reading and validating each goal's configuration.
Is there a way to reuse one goal within another?
Thanks,
Don
Is there a way to reuse one goal within another?
AFAIK, the Maven API doesn't offer any facility for this because the Maven folks don't want to promote a practice leading to strong coupling between plugins which is considered as bad. You'll find background on that in Re: calling plugin in another plugin?.
That being said, this blog post shows how you could instantiate a Mojo and use reflection to set its field before to call execute.
You might also want to check the mojo-executor library.
But be sure to read the mentioned thread, I think it's important.
Of course, I could just have goalX delegate to ClassX for most of it's functionality, then when goal5 is invoked, it delegates to Class1...Class4, but this still involves a certain amount of code duplication in terms of specifying, reading and validating each goal's configuration.
So then why not provide a common class for your other classes for the purpose of goal validation? I think the easiest thing to do here is to have one goal invoke the other in your code.
The "Maven mindset" appears to be that configuration is the responsibility of the pom.xml author, not the Mojo implementor. If you move all your configuration and such into a common base class, you end up bypassing this mechanism.
It kind of sounds like what you want are sub-projects: Each of your goals 1-4 live in their own project, or you can run goal 5, which runs them all. Perhaps this might help?: http://i-proving.com/space/Technologies/Maven/Maven+Recipes/Split+Your+Project+Into+Sub-Projects
If your source trees don't split nicely along project lines, you might be able to do something with profiles (though I haven't tried this). Check out the accepted answer here: How to bind a plugin goal to another plugin goal.
Related
I am trying to build a core module to be used across services, its collection of enum and interfaces with(without) default implementation only. Wanted to know if its possible to impose this rule either as part of mvn build or ci flow to check if someone has pushed a class in it. Being able to done at mvn would be preferred though.
Is this even possible? If yes can someone point me how?
Not sure which is the best way but I would suggest a custom rule on sonar/findbugs/checkstyle/pmd with the appropriate plugin.
Or a custom annotation processor that you use at compile time.
I am new to Cucumber and I am using cucumber-java. The cucumber feature files look great. However, the reuse of step definitions really gets in the way about organizing the step definition code. The most intuitive way for me to organize the step definitions is just to follow the organization of the feature files, namely, one class for one feature. However, this way is screwed if there are two identical steps in two feature files, because you will miss one step in one of the classes, which breaks the coherence of the entire structure. However, I cannot convince myself to use other ways right now. So, what is a sensible way to organize step definitions when using cucumber-java?
Thank you very much.
Start with the way you are already doing and once you recognize that a step is reused, move it a class ReUsableSteps or something. This way, if a step does not exist in its class then it should be in ReUsableSteps. Just a thought.
You can have a separate package as placeholder for classes that defines common steps. Add that package as glue.
The best way to use cucumber is to minimize the duplication of step definition. What we should focus on while writing step definition is to avoid any code specific to a class or functionality in steps method of StepDefinition class because that way it can not be generalized, it should have common code which can be used for different steps and code for propagating to separate class for which step is meant and specific logic for each step should reside in separate class. This way we can avoid duplication.
Example:-
Suppose we have component feature file which contains step "Component A has to receive responses", its implementation class is ComponentStepDefinition class, when we implement this in step definition we should not use any logic for iterating or calculating responses for component A there, rather pass the value to a class which performs A related task, in this way to you have to implement "Component B has to receive responses" then same step definition can be used and B's logic will be in another class.
Sort your step definitions by common functionality as related to your domain. They do not have to be linked to specific feature files.
For example, one of our features is to provide our partners with scores (how are they doing on our platform). We have several step definitions related to those scores in a ScoreSteps file. We might have other steps related to partners, those would be in a PartnerSteps file. This also makes it easier to use helper methods related to a certain domain object.
These files would be completely different for you, depending on your domain.
Also note that your IDE will know if a step has already been defined or not (at least, in IntelliJ steps that are undefined are marked in yellow).
Reusing steps is critical for maintenance reasons. That doesn't mean trying to shoehorn steps here and there, but finding a balance between reusability and understanding. As already said above, arranging them into a Common or Reusable package is a pretty good idea. This is something to be done as you go, because you don't always know whether a step is going to be reused or not. In this sense, frequent refactoring of step definitions will be quite normal. Actually it is an indicator of code aliveness, so don't hesitate to make any changes to get the test scenarios clear enough and the testing code as clean as possible. It is just the same well-known coding principles, applied to testing.
One thing that helped me with this task was a utility class (actually it was a set of classes) that allowed me to know which steps and steps definitions exist, the class in which the step definition is defined, the feature files and test scenarios that make use of them, etc. You can even implement advanced options such as searching for steps or steps definitions that contain such and such keywords, or getting to know the step definitions that are not used any longer, etc. Kind of a dictionary.
It can be achieved by either processing the java classes that belong into the 'glue' folder and gather all the regular expressions associated to the gherkin annotations, or by parsing the feature files with the help of a Gherkin parser. Although you may want to have both approaches implemented, as they are not mutually-exclusive; on the contrary, they complement each other.
This is something you may not need when having just a few test scenarios. But as this number grows bigger and bigger, you will find such a mechanism really valuable.
This can be done easily by using multiple test runner classes for multiple feature files.
You can create same steps for different features as long as you are specifying the glue code in your test runner. Glue will make sure the cucumber checks only in the path specified for the steps during execution.
Then you can maintain a suite xml configuration like TestNG.xml for running which all features I want.
#RunWith(Cucumber.class)
#CucumberOptions(monochrome = true, features = "src/test/java/com/abc/batch/xyz/payout/bbq/monthly",
plugin = { "pretty", "html:target/cucumber-html-reports" }, strict = true, glue = {"com.abc.batch.xyz.payout.bbq.monthly" })
#Rollback(false)
The way I organize my cucumber tests are like I have a java package for a cucumber feature where I will have the steps definitions class, feature file, test data files for those tests and Hooks class.
The advantage is that when I try to look for the step definitions in the step class, I know where exactly to look at and the chances of getting a step definition conflict is zero unless you have added the same definition in that package twice.
The problem scienario is as follows (Note: this is not a cross-jar dependency issue, so tools like JarAnalyzer, ClassDep or Tattletale would not help. Thanks).
I have a big project which is compiled into 10 or more jar artifacts. All jars depend on each other and form a dependency hierarchy.
Whenever I need to modify one of the jars, I would check out the relevant source code and the source code for projects that depend on it. Modify the code, compile, repackage the jars. So far so good.
The problem is: I may forget to check one of the dependent projects, because inter-jar dependencies can be quite long, and may change with time. If this happens some jars may go "out-of-sync" and I will eventually get a NoSuchMethodException or a some other class incompatibility issue at run-time, which is what I want to avoid.
The only solution I can think of, the most straighforward one, is to check out all projects, and recompile the bunch. But this takes time, especially if I re-build it every small change. I do have a continuous integration server, that could do this for me, but it's shared with other developers, so seeing if the build breaks is not an option for me.
However, I do have all the jars so hypothetically it should be possible to verify jars which depend on the code that I modified have an inconsistency in method signature, class names, etc. But how could I perform such check?
Has anyone faced a similar problem before? If so, how did you solve it? Any tools or methodologies would be appreciated.
Let me know if you need clarification. Thanks.
EDIT:
I would like to clarify my question a little bit.
The ultimate goal of this task is to check that the changes that I have made will compile against the whole project. I am looking for a tool/technique that would aid me perform such check.
Consider this example:
You have 2 projects: A and B which are deployed as A.jar and B.jar respectively. A depends on B.
You wish to modify B, so you check it out and modify a method signature that A happens to depend on. You can compile B and run all tests by itself without any problems because B itself does not depend on anything. So you happily commit your changes.
In a few hours the complete project integration fails because A could not be compiled!
How do I avoid this?
The kind of tool I am looking for would retrieve A.jar and check that all dependencies in A on the new modified B are still fine. Like a potential compilation error that would happen if I were to recompile A and B sources together.
Another solution, as was suggested by many of you, is to set up a local continuous integration system that would recompile the whole project locally. I don't mind doing this, but I want to avoid doing it inside my workspace. On the other hand, if I check-out all sources to another temporary workspace, then I need to mirror my local changes to the temporary workspace.
This is quite a big issue in my team, as builds break very often because somebody forgot to check out (or open in Eclipse) the right set of projects. I tried persuading people to check-out source and recompile the bunch before commits, but not only it takes time, it needs running quite a few commands so most people just find it too troublesome to do. If the technique is not easy or automated, then it's unusable.
If you do not want to use your shared continuous integration server you should set up a local one on your developer machine where you perform the rebuild processes on change.
I know Jenkins - it is easy to setup (just start) on a local machine and I would advice to run it locally if no one is provided in the IT infrastructure that fits your needs.
Checking signatures is unfortunately not enough. Having the correct signatures does not mean it'll work. It's all about contracts and not just signatures. I mean what happens if the new version of a library has the same method signature, but accepts an ArrayList parameter now in reversed order? You will run into issues - sooner or later. I guess you maybe consider implementing tools like Ivy or Maven:
http://ant.apache.org/ivy/
http://maven.apache.org/
Yes it can be pain to implement it but once you have it it will "guard" your versions forever. You should never run into such an issue. But even those build tools are not 100% accurate. The only proper way of dealing with incompatible libraries, I know you won't like my answer, is extensive regression testing. For this you need bunch of testing tools. There are plenty of them out there: from very basic unit testing (JUnit) to database testing (JDBC Proxy) and UI testing frameworks like SWTBot (depends if your app is a web app or thick client).
Please note if your project gets really huge and you have large amount of dependencies you always not using all of the code there. Trying to check all interfaces and all signatures is way too much. Its not necessary to test it all when your code use lets say 30 % of the library code. What you need is to test what you really use. And this can be only done with extensive regression testing.
I have finally found a whole treasure box of answers at this post. Thanks for help, everyone!
The bounty goes to K. Claszen for the quickest and most input.
I'm also think that just setup local Jenkins is a best idea. What tool you use for build? Maybe you can improve you situation with switching to Maven as build tool? In more smart and don't recompile full project if you don't ask it directly. But switch to in can be HUGE paint in the neck - it hardly depends on how you project organized now...
And about VCS- exist Mercurial/SVN bridge - so you can use local Mercurial for you development ....
check this link: https://www.mercurial-scm.org/wiki/WorkingWithSubversion
There is a solution, jarjar, which allows to have different versions of the same library to be included multiple times in the dependency graph.
I use IntelliJ, not Eclipse, so maybe my answer is too IDE-specific. But in IntelliJ, I would simply include the modules from B into A, so that when I make changes to A, it breaks B immediately when compiling in the IDE. Modules can belong to multiple projects, so this is not anything like duplication, it's just adding references in the IDE to modules in other projects.
I've been asked to work on changing a number of classes that are core to the system we work on. The classes in question each require 5 - 10 different related objects, which themselves need a similiar amount of objects.
Data is also pulled in from several data sources, and the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
I'm beginning to get overwhelmed with this task. I have tried unit testing with JUnit and Easymock, but as soon as I mock or stub one thing, I find it needs lots more. Everything seems to be quite tightly coupled such that I'm reaching about 3 or 4 levels out with my stubs in order to prevent NullPointerExceptions.
Usually with this type of task, I would simply make changes and test as I went along. But the shortest build cycle is about 10 minutes, and I like to code with very short iterations between executions (probably because I'm not very confident with my ability to write flawless code).
Anyone know a good strategy / workflow to get out of this quagmire?
As you suggest, it sounds like your main problem is that the API you are working with is too tightly coupled. If you have the ability to modify the API, it can be very helpful to hide immediate dependencies behind interfaces so that you can cut off your dependency graph at the immediate dependency.
If this is not possible, an Auto-Mocking Container may be of help. This is basically a container that automatically figures out how to return a mock with good default behavior for nested abstractions. As I work on the .NET framework, I can't recommend any for Java.
If you would like to read up on unit testing patterns and best practices, I can only recommend xUnit Test Patterns.
For strategies for decoupling tightly coupled code I recommend Working Effectively with Legacy Code.
First thing I'd try to do is shorting the build cycle. Maybe add in the options to only build and test the components currently under development.
Next I'd look at decoupling some of the dependencies by introducing interfaces to sit between each component. I'd also want to move the coupling out in the open most likely using Dependency Injection. If I could notmove to DI I would have two ctors, on no-arg ctor that used the service locator (or what have thee) and one injectable ctor.
the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
Is that without meant to be a with? I would look at moving as much into POJOs as you can so it can be tested without needing to know anything EJB-y.
If you project can compile with Java 1.5 you shoul look at JMock? Things can get stubbed pretty quickly with 2.* version of this framework.
1.* version will work with 1.3+ Java compiler but the mocking is much more verbose, so I would not recommend it.
As for the strategy, my advice to you is to embrace interfaces. Even if you have a single implementation of the given interface, always create an interface. They can be mocked very easily and will allow you much better decoupling when testing your code.
In our infrastructure, we have lots of little Java projects built by Maven2. Each project has its own pom.xml that ultimately inherits from our one company "master" parent pom.
We've recently started adding small profiles to our parent pom, disabled by default, that, when enabled, execute a single plugin in a conventional manner.
Examples:
The 'sources' profile executes the maven-source-plugin to create the jar of project sources.
The 'clover' profile executes the maven-clover2-plugin to generate the Clover report. It also embeds our Clover license file so it need not be re-specified in child projects.
The 'fitnesse' profile executes the fitnesse-maven-plugin to run the fitnesse tests associated with the project. It contains the fitnesse server host and port and other information that need not be repeated.
This is being used to specify builds in our CI server like:
mvn test -P clover
mvn deploy site-deploy -P fitnesse,sources
and so on.
So far, this seems to provide a convenient composition of optional features.
However, are there any dangers or pitfalls in continuing on with this approach (obvious or otherwise)? Could this type of functionality be better implemented or expressed in another way?
The problem with this solution is that you may be creating a "pick and choose" model which is a bit un-mavenesque. In the case of the profiles you're describing you're sort of in-between; if each profile produces a decent result by itself you may be ok. The moment you start requiring specific combinations of profiles I think you're heading for troubles.
Individual developers will typically run into consistency issues because they forget which set of profiles should be used for a given scenario. Your mileage may vary, but we had real problems with this. Half your developers will forget the "correct" combinations after only a short time and end up wasting hours on a regular basis because they run the wrong combinations at the wrong time.
The practical problem you'll have with this is that AFAIK there's no way to have a set of "meta" profiles that activate a set of sub-profiles. If there had been a nice way to create an umbrella profile this'd be a really neat feature. Your "fitnesse" and "sources" profiles should really be private, activated by one or more meta-profiles. (You can activate a default set in settings.xml for each developer)
There isn't a problem with having multiple profiles in Maven, in fact I think they are an excellent way of allowing your build to enable and disable classes of functionality. I'd recommend naming them based on their function rather than the plugin though, and consider grouping functionally related plugins in the same profile.
As a precedent for you to follow, the Maven super POM has a "release-profile" defined, which includes configurations for the source, javadoc, and deploy plugins.
You should consider following this approach, so your "fitnesse" profile would become "integration-test", and you could choose to define additional plugins in that profile if needed at a later date. Similarly the "clover" profile could be renamed "site", and you could define additional reports in that profile, e.g. configurations for the JDepend, JXR, PMD plugins.
You seem slightly suspicious towards that approach, but you're not really sure why - after all, it is quite convenient. Anyway, that's what I feel about it: I don't really know why, but it seems somewhat odd.
Let's consider these two questions:
a) what are profiles meant for?
b) what are the alternative approaches we should should compare your approach with?
Regarding a), I think profiles are meant for different build or execution environments. You may depend on locally installed software, where you would use a profile to define the path to the executable in the respective environments. Or you may have profiles for different runtime configurations, such as "development", "test", "production".
More about this is found on http://maven.apache.org/guides/mini/guide-building-for-different-environments.html and http://maven.apache.org/guides/introduction/introduction-to-profiles.html.
As for b), ideas that come to my head:
triggering the plug-ins with command line properties. Such as mvn -Dfitnesse=true deploy. Like the well known -DdownloadSources=true for the eclipse plugin, or -Dmaven.test.skip=true for surefire.
But that would require the plugin to have a flag to trigger the execution. Not all the plug-ins you need might have that.
Calling the goals explicitly. You can call several goals on one command line, like "mvn clean package war:exploded". When fitnesse is executed automatically (using the respective profile), it means its execution is bound to a lifecycle phase. That is, whenever that phase in the lifecycle is reached, the plugin is executed.
Rather than binding plugin executions to lifecycle phases, you should be able to include the plugin, but only execute it when it is called explicitly.
So your call would look like "mvn fitnesse:run source:jar deploy".
The answer to question a) might explain the "oddness". It is just not what profiles are meant for.
Therefore, I think alternative 2 could actually be a better approach. Using profiles might become problematic when "real" profiles for different execution or build environments come into play. You would end up with a possibly confusing mixture of profiles, where profiles mean very different things (e.g. "test" would denote an environment while "fitnesse" would denote a goal).
If you would just call the goals explicitly, I think that would be very clear and flexible. Remembering the plugin/goal names should not be more difficult that remembering the profile names.