We have a multi-module maven project. One of the modules has a bunch of .proto files, which we compile to java files. Pretty much every other module depends on this module. Most of them use Protobuf 2.4, but one needs to use 2.5.
Is there any nice way to do this? (The not nice way is to edit the pom file to say "2.5", build a jar, manually copy that jar to wherever we need it, and then change the pom file back to 2.4.)
Never used protobuf, but, as I understand it's a plugin that generate stuff.
So I'm gonna give you generic pointer hoping it will help.
I think you should either try to make 2 jar with different classifier from a single module, see https://maven.apache.org/plugins/maven-jar-plugin/examples/attached-jar.html
For example classifier proto2.4 and proto2.5
then you can add the classifier when you define the dependency to that module.
Other option I see is having 2 modules, the real one, you have now, and another one for 2.5
Generate a zip from the main one and the second module would be empty but have a dependency on the generated zip, unzip it and then compile with the plugin config for 2.5
Slower at execution, a bit dirtier imho, but can be needed if for example you need more customization than just the version.
I finally got things to work more or less how I wanted. I created a new module with JUST a pom file; that pom file refers to the proto files of the original module, but compiles them with the proto2.5 compiler and puts the result into its own directory.
Related
I am still fairly new to Java, and am trying to restructure one of my Java projects for the Java 9 module structure, and it seems like I need to do everything completely manually. I am hoping I am simply missing some steps somewhere in the correct way to be handling my dependencies:
Old Way (Java 8 and older)
I create my project.
I add my dependencies to the pom
I code.
I compile.
New Way (modules)?
I create my project.
I create my modules.
I create a project level .pom that defines my dependencies for all of the modules
I manually add each dependency to each module it will be used in. If I need to update a dependency, I remove the old one from each module and put the new one in, after updating the Maven .pom (this means someone cloning my project from git has to figure out all the dependencies as well, since .iml files aren't just a list of dependencies and don't generally get put on git)
I manually add every possible package a module might need to the module-info file, since there is no autocomplete otherwise, once again, manually updating the list of requires statements if the dependency is changed.
I code.
I remove all of the unused packages from the module-info file.
I compile the code.
This just seems inefficient. Is there a better / correct way I should be doing this? This is the process that their documentation indicates I should be using. ( see: https://www.jetbrains.com/help/idea/creating-and-managing-modules.html#working-with-module-dependencies )
Yes, I know I don't have to add all the packages manually and can just search on the command line to figure out where a class I want to use is located, but that just takes even longer.
Java 9 / 10. I have been struggling with a simple project for more than a week.
As you can see in the picture, I want to use commons-collections as an automatic module (I have tried to add it with maven but that did not work out well).
So, I have red that I need to put the jar onto the module-path. Where does IntelliJ take this modulepath from? How can I tell the IDE to add commons-collections into the project so that
1. the compiler can find it at compile time and
2. Maven can find it at build time?
Anyone can help?
EDIT:
I have tried to add it in the project-structure dialog as a module dependency in all kinds of different combinations. I have literally tried hundreds of things, moved the jar around in the structure and I cannot find a simple enough doc to tell me how to do this.
I have used compiler options to add "--module-path automatic" (module specific and general compile options) in order to make IDEA find the thing and let Java make an automatic module out of it.
You need to add a library entry first, to make it available under Modules:
Step 1: Add a library (Add -> Java -> jar file)
Step 2: Select the module (remember to click "Apply")
After that, the module-info.java file will be successfully validated:
Intellij uses a module path if you run a program from an (intellij) module containing module-info.java, otherwise it will use a classpath.
I tried importing common4 as a module, it does seem to work for me, but I had to use a different 'requires' argument as compared to yours. Your 'requires' is 'commons.collections4', mine is 'org.apache.commons.collections4' (check the commons4 manifest entry for the highlighted Automatic-Module-Name and use that instead).
If the Automatic-Module-Name is missing from the commons4 manifest (it is absent from version 4.1 and earlier), Java may not detect the jar as a module if the name contains digits or illegal characters. Some maven repository jars therefore will not work and intelli will not see those jars as modules.
You can also check for a bad filename by using the following command:
jar --file=/path/to/jar --describe-module
If the command fails, it's likely that the jar does not have an Automatic-Module-Name entry and that the filename is poorly named.
ok
jar --file=C:\temp\jigsaw1-1.0.jar --describe-module
bad
jar --file=C:\temp\jigsaw1.0.jar --describe-module`
'jigsaw1.0: Invalid module name: '0' is not a Java identifier'
Some maven jars may therefore fail to be detected as modules as they tend to look similar.
I currently manage a few separate Maven projects in which I use Protobufs as a serialization format and over the wire. I am using David Trott's maven-protoc plugin to generate the code at compile time.
All is good and well until I want those project to communicate between one another — or rather, use each other's protobufs. The protobuf language has an "import" directive which does what I want but I'm faced with the challenge of having project A exporting a ".proto" file (or possibly some intermediate format?) for project B to depend upon.
Maven provides a way for a project to bundle resources but AFAIK, these are meant to be used at runtime by the code and not by a goal during the compile / source generation phase — at least I haven't been able to find documentation that describes what I want to achieve.
I've found another way to achieve, and it doesn't involve any Maven magic. Diving into the code for the maven-protoc plugin, I found that this is a supported use case -- the plugin will look for and collect and .proto files in dependent jars and unpack them into a temporary directory. That directory is then set as an import path to the protoc invocation.
All that needs to happen is for the .proto file to be included in the dependency's package, which I did by making it a resource:
projects/a/src/main/resources/a.proto
Now in projects/b/pom.xml, add 'a' as a regular Maven dependency and just import a.proto from b.proto as if it existed locally:
b.proto:
import "a.proto";
This isn't ideal, since files names may clash between various projects, but this should occur rarely enough.
You can package your .proto files in a separate .jar/.zip in the project where they are generated, and publish them in your repository using a dedicated classifier. Using the assembly plugin might help here to publish something close to "source jars" that are built during releases.
Then, on projects using them, add previously created artifact as dependency.
Use the dependency plugin with the "unpack-dependencies" goal, and bind it to a phase before "compile".
I developing a web application with a lot of libraries like, Spring, Apache CXF, Hibernate, Apache Axis, Apache Common and so one. Each of these framework comes with a lot of *.jar libraries.
For development I simple take all of the delivered libraries and add them to my classpath.
For deployment not all of these libraries are required, so is there a quick way to examine all the required libraries (*.jar) which are used by my source code?
If you move your project to use Maven such things become easier:
mvn dependency:analyze
mvn dependency:tree
For your example, Maven + IDE + nice dependency diagrams could help allot.
See an example of this : it's much easier this way to figure out what happens in a project, and this way you don't need to add to your project "all delivered libraries" - just what it's required.
JDepend traverses Java class file
directories and generates design
quality metrics for each Java package.
JDepend allows you to automatically
measure the quality of a design in
terms of its extensibility,
reusability, and maintainability to
manage package dependencies
effectively.
So, as a quick, dirty, and potentially inefficient way, you can try this in Eclipse:
Create two copies of your project.
In project copy #2 remove all the jars from the classpath.
Pick a source file that now has errors because it can't resolve a class reference. Pick one of the unresolved classes and note its fully qualified class name.
Do Control-Shift-T and locate the unresolved class. You should be able to see which jar its contained in since all the jars are still in the classpath for project copy #1.
Add the jar that contains this unresolved class back into your classpath in project copy #2, then repeat steps 3 and 4 until all class references are resolved.
Unfortunately you're not done yet since the jar files themselves may also have dependencies. Two ways to deal with this:
Go read the documentation for all the third-party packages you're using. Each package should tell you what its dependencies are.
Run your application and see if you get any ClassNotFoundExceptions. If you do, then use Control-Shift-T to figure out what jar that class comes from and add it to your classpath. Repeat until your project runs without throwing any ClassNotFoundExceptions.
The problem with #2 is that you don't really know you've resolved all the dependencies since you can't simulate every possible execution path your project might take.
My Maven 2 project consists of several sub-modules. It s structured containing and EJB, WAR and Jar sub modules.. Now i want to instrument the packaged EAR that contains all submodules as mentioned.
Example:
Interface Maven Project consists of several modules:
- InterfacePOM --> parent pom
- InterfaceEAR --> EAR module which does not actual code but is the packaging for Domain, EJB and WAR
- InterfaceEJB --> EJB module
- interfaceWAR --> WAR module
- interfaceDomain --> JAR module
When using Cobertura i can succesfully instrument all various independent modules but that generated a .ser file per module. Is there a way to instrument an enitre EAR file at once? So that the result will be a single .ser file which i can use??
Short answer: no (have a look at this previous answer for more details). You'll need an external plugin like the dashboard (actually, don't use it, see my previous answer), XRadar or Sonar to aggregate the reports. But in this area, Sonar is the clear winner (this project just rocks) and I'd recommend it without any hesitation. Check out Nemo, their public instance, pick up any project and have a look at the drill down of code coverage (for example Apache CXF) to get an idea of what it can do.
UPDATE: It appears that I missed the point of the initial question so I'm updating my answer accordingly. Basically, I now understand the question as "how to instrument an ear with cobertura" and this is indeed a totally different story.
Unfortunately, while cobertura can instrument an ear, sar, zip, war, jar, I' don't think that the cobertura-maven-plugin supports this out-of-the-box and it may be a better option to use cobertura's ant task with the antrun plugin. See MCOBERTURA-86, this thread and this discussion for more background on this (and an antrun sample).
TBH, what you are trying to do is really not easy in terms of build lifecycle, packaging, reporting, etc and is going to be a tough task because of the lack of support from the cobertura plugin. I'd really think about it twice (time to invest to get the whole thing working vs the value generated) or consider spending that time (understand money) to get a clover license (which offers better support for this).
I implemented a solution now based on your previous answers around Maven 2. It is still not very easy to use but so far it goes OK. The implementation is as follows:
1. Modified my parent pom to generate cobertura instrumented classes when giving a specific profile.This generates the .ser files and the instrumented classes.
2. The instrumented classes are copied to the /target/classes folder by using the maven-resource-plugin, so the actual packaging uses the instrumented classes.
3. As there is no module wide .ser file i manually combine those .ser files from the EJB,WAR,JAR and ear file using the commandline solution given by Cobertura. coberture-merge.bat/.sh
4. Deploy the .ser file into my JBoss container and also deploy the instrumented EAR.
5. After testing i run a report on the merged .ser file and voila.. it seems to work..
I surely will look into Clover as the solution implemented is somewhat manual..
It looks like there is no task in the cobertura-maven-plugin for merging .ser files from individual projects into a single report.
A google search turned up this feature request and patch for the plugin to add a merge task, but it doesn't look like it was accepted. One of the comments suggests using the dashboard plugin to accomplish the same thing, you might have some success with that.