Location of generated source files for maven directory structure - java

Besides src/main/java folder, we have one folder that contains some generated java sources that are required for the main sources. Code generation is invoked manually, when needed. Generated source is checked into the source repo. Everything will be built and packed together.
What would be the best location for generated java sources that are going to be compiled together with main sources? Should it be:
/src/generated/java (following the same naming logic for src/testInt/java for integration tests)
/generated-src/main/java (in collision with "The src directory contains all of the source material for building the project")
/src/main/generated-java (well... generated-java is not a type)
...?
The first option seems like the most appropriate one for this case. What do you think? Is there anything in Maven docs that describes this situation (that I have overlooked)? Do you know any repo with similar structure?
Thank you.
Answer
As suggested by #Absurd-Mind, direction we are thinking about is to split the source into the submodules (which works nice in gradle). So, the generated source and some other related source will go into its own submodule (they will produce the separate artifact) and the rest will go in other submodule, that uses this one. Thank you.

I think the location depends on how the source is generated and handled.
The source code is generated automatically during the build process: Then i would use target/main/java/, target/test/java/ and so on. This code is not checked in into CVS since you can rebuild it fairly easy. In case you clean your project the target directory will be removed and the source will be rebuild.
The source code is generated manually by an external tool or similar: I would use generated/src/main/java/, generated/src/test/java/, generated/src/main/resources/ and so on. This code should be checked in. A benefit is, as soon you see that the top-level directory name is generated you know that all files/directories below are also generated. Also you have the standard maven directory structure under the top-level directory. Another point is that clean-up is easy, just delete generated and recreate it, without looking through many other directories (like in your example: src/main/generated-java and src/test/generated-java).
EDIT: Another nice solution would be to create a maven project which only contains the generated source like myproject-generated-1.0.3.jar. This project would be a dependency in your real application. Then you would just put your generated source int src/main/java.

As much as i know there is no standard folder structure for generated sources. In my projects, i prefer src/gen/java kind of notation.

I totally agree with the accepted answer. I just want to offer a slightly different suggestion for naming the directory that contains code generated by third-party tools:
src-gen/main/java
Background: In the Eclipse/Maven Tycho world (where code/resource generation often plays a large role) there is the src-gen directory for generated code, which has been established as some kind of standard convention. (the default project layout is a bit different compared to Maven, as all source files are directly in src and src-gen).
In a Maven project that could be translated for example to src-gen/main/java, src-gen/main/resources, src-gen/test/java, src-gen/test/resources. I like that more than moving everything into a "generated" directory, because
Sources in src/main/javaand src-gen/main/java are on the same depth in the directory tree
It's more clear that src-gen contains generated sources/resources that contribute to the build. On the other hand a folder just named "generated" dosn't tell you much about its content. It could contain anything, like generated documentation or generated test data or it could be just a temporary folder.
All the mentioned advantages of generated/src/main/java still apply (e.g. easy cleanup)
After a quick google search it looks like there are already projects on Github that use this pattern
Some thoughts/opinions about the other suggestions from the question:
Instead of /src/main/generated-java I would probably rather go with something like /src/main/java-gen which, when sorting directories alphabetically, keeps generated and regular code next to each other (<lang>-gen is also another pattern already used in Eclipse projects)
In my opinion gen fits in with the brief official names like src, it etc. more than generated. I've already seen src/gen/java a few times in the wild and have the feeling it is a more common than /src/generated/java. On the other hand some Maven plugins use the quite verbose target/generated-sources/<lang> directory, so generated-sources/main/java could also be an option if your not into short names...
Ultimately I think the naming doesn't matter that much and it is up to your preference since none of this is "official" convention.

NetBeans adopted <project>/target/generated-sources/<tool> as the location for generated code. As a result you would see an extra leaf appear in your project tree named as Generated Sources (<tool>), and source code will be navigable and not show up with compiler errors in the markup.
So if you commit your code, it will not be under the /target directory, and you will have to setup your maven project for the additional Source Code locations. Otherwise, I will suggest to keep with that adopted standard and put things under <project>/target/generated-sources/<tool>.

In Maven project source file store inside src/main/java , src/main/resources and test class store inside src/test/java.
In Maven generated code (Compile code) stored into target/ folder.
When you build your Maven project, all generated code to be updated in target folder.

Related

How to share common files between several projects in Java

Suppose that I have a common directory that contains general-purpose files like FileUtils.java and ImageUtils.java. Also I have two projects that should use these common files. What is the most Java-way to import them into these projects? Just add path manually to the -classpath option when using javac and java? Build them into one jar file? Or something else?
Just follow simple steps:
1.) Have module say, companyname-commons-util
2.) build to a jar file, companyname-commons-util.jar
3.) Add dependency of this jar into other projects, and just reuse the classes. (maybe maven, gradle or explicitly adding into classpath)
** The same can be reused in other projects as well. Good from maintenance point of view, and keeping project structure intact.
The recommendation would be to create a third project and then use that to generate a JAR file; you can then use that reference in your other projects. If you're using Maven to build them you'd end up with a different module with your common code in place.
Besides the things that have been said; a word of warning: try to slice your projects aka components to be as small as possible.
In other words: before just blindly going forward and pushing all content of your "common" folder into its own project it might be worthwhile to step back and carefully look at
a) the contents of common
b) how other projects make use of that source
And theoretically, you match that whole picture with the thing that is called "architecture" (which may or may not exist for your overall "product") to understand where "reality differs from as-it-should-be".
Then, finally, you define one or more projects that cover all (or parts of) your source code in "common"; and then you change your whole infrastructure so that other "dependent" projects do not rely on using your "common" source files but some kind of build artifact.

Why JAR Files Do Not Contain Documentation?

I'm in the process of writing a small Java library that contains a related code that I usually include in most of my android app. I decided to export the library as a jar file then drop the file in the libs folder of my future projects.
Using Android Studio:
I created a Java Library module and put my code in it. And I added some comments to some of the method, following this.
Then, I ran the jar task in gradle, which gave me the .jar file in build/libs directory of my module.
Now, when I used this jar in one of my android apps, Everything works as expected, except the Doc part. When I hover over the classes and methods of my library, I don't see the Doc comments that I wrote.
Q1: Am I missing another step?
Q2: Are jar files supposed to have no comments?
The javadocs are the documents that are generated from the javadoc comments in your source code. They are not part of a normal JAR file because that would unnecessarily bloat the JAR files ... with stuff that someone running to code doesn't need.
The javadocs can be generated by a Gradle task, by the javadoc command (if you have a Java SDK installed) and by various other tools. You can then read them using a web browser.
On the other hand, IDEs can often render the javadoc comments in source code and display them as pop-ups, etcetera. (Some people would call this "javadocs", but I think that is an overstatement, since you typically can't navigate the documentation ... like you can with read javadoc documents.)
In order to render the javadoc comments, the IDE needs the source code. JAR files don't (normally) contain any source code or javadocs. Instead, the normal way to deal with this is to tell the IDE where the source code is, either by pointing it at a source code directory, a ZIP file containing source code, or URL for downloading the source code.
(I don't use Android Studio, so I can tell you exactly how to do this. However, I imagine that the IDE's online help explains how to do it ...)
It seems that your end goal here is to distribute your libraries in a way that allows programmers to see the javadoc comments.
The simple way to do that is to distribute source code. This Q&A describes how to get Gradle to generate a separate archive containing the source code, or add the source code to the JAR containing your compiled code1.
If that isn't acceptable, you may need to generate the javadocs as HTML2 and provide the HTML tree as a separate ZIP file that a programmer can unzip and read with a web browser. Alternatively, put the javadocs up on a website.
1 - I would not recommend this. People who just want to use the JAR as a binary are liable to complain about "bloat".
2 - If neither providing source code or javadoc HTML documentation is acceptable, I don't think there is a pragmatic solution.
There is a separate Gradle task to generate javadoc. Try adding the following:
task javadocJar(type: Jar, dependsOn:javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir }
And then run:
gradle javadocJar
See if that helps.
In addition to the above, you can try and add the following to make to generate a single jar with both compiled classes and javadoc:
jar {
from javadoc.destinationDir
}
jar.dependsOn javadoc
I don't know if that's the right decision to bundle everything in the same jar. I prefer keeping the jars separate and maybe find another way to make the IDE use the javadoc jar file. Maybe try adding the javadoc jar as another dependency of the module.
Yes This is possible
Hi, This is possible but with a small change like in the jar file.
First of all, from a code point of view jar file contains only compiled ".class" files and not source files ".java"
So if you need a doc to be applied with a jar by this I mean not the index.html which gets created but the comment that appears whenever a person uses the jar API and calls a method with a suggestion.
Example :
For that, we need to also add a source file while generating .jar file.
Steps for the same:
Type comments/java docs in code
Generate Docs
This will create a doc folder in project folder
Now create jar file
Make sure you choose this option as shown below
Almost done just test it by importing jar to another project and it should the suggestions as per docs
Very Important this can be harmful as you are including source files.java in your jar so before making make sure if you need this or not.!!!!
Hope this gave your answer
Any questions you can contact me over: VaibhavMojidra.com

Eclipse - record and apply move and rename refactorings to another workspace

I'm currently working in a big java project with quite a few submodules that are worked on by different teams. Some of these teams are building the "framework", others are building the "application" based on the framework.
When the framework guys move or rename a class, the applications guys get compile errors wherever they are using a refactored framework class. Is there a way in Eclipse (Galileo Release) to record the change and update the references in another workspace?
What I've tried so far is creating a refactoring script during the rename refactoring, but when I try to apply that script to another workspace, it fails with The refactoring 'Rename Type' (org.eclipse.jdt.ui.rename.type) cannot be performed, since its input 'xxx.TestClass" does not exists. Well, it does not exist (anymore) alright, but what I want is for all references for xxx.TestClass in my project to be changed to xxx.MyRenamedTestClass. Is there a way in Eclipse to do this with built-in functionality or an existing plugin or do I have to write one myself?
Thanks for your help!
EDIT: By now I found out that the "Migrate JAR"-Plugin provides the functionality I am looking for, although we build our JARs with Maven, not Eclipse. I'm going through the source code now to find out what parts I can reuse.
Answering my own question to get some closure here.
The easiest way to do it is to use the Migrate JAR File... refactoring which uses a refactoring script in META-INF called REFACTORINGS.XML. You can get a JAR with this included automatically by using Export JAR in Eclipse. We build with Maven and thus just do Refactoring->Create Script... and put it into the appropriate position in the JAR.
The JDT-internal code that Migrate JAR executes creates Stubs for the source classes in a temporary source folder, so it actually executes the refactoring first and then updates the references. The user never gets to see these temporary files.

Linking source to .jars in Eclipse

This framework distribution includes a lib folder (where all the binary .jars are) and a src one (where you can find the corresponding .javas for each .jar). So far I only have added lib to the Java project build path.
How would you copy src now? Just adding it or is there a way of somehow link it to lib? I don't have in mind what the gain would exactly consist of but I reckon that that would be somewhat better.
Edit - src is provided as a folder hierarchy, not source .jars.
If you're not modifying the source, performance will be better if the source for each jar is in its own source jar. It's usually also more convenient. This is a convention at this point - especially if you can get the jars from a maven repository. Each jar should be organized as you'd expect, with top level directory(s) "org", "com", etc. In the build path, you can attach a source jar to each binary jar.
I'm not 100% sure this is what you're looking for, but if you have added jars to your build path, you can right click on individual jars in the Project Explorer and select Properties. In the resulting pop-up is a Java Source Attachment tab, which has options for linking source files depending on where they're located.
The main advantage to this that I'm aware of is when you're debugging code that makes use of the jars. If you have source attached, you can step through the code, including comments (which are not available if you use a de-compiling tool to step through classes for which you don't have source).

How to open existing Java 'solution' (not developed in Eclipse) using Eclipse?

I've been tasked with picking up someone elses Java code and adding some functionality to it.
I'ved pull down the source tree from CVS and see a bunch of .jar files in different folders. I'm guessing the developer did not use Eclipse.
I am new to Java (coming from .NET background) and have used Eclipse so far to create one Java project. I'm wondering now that I have this guys files (he has classpath.jar and other .jar files along with some subfolders each with 'java' files in them), how do I open them? I tried opening one at a time, etc.. but doesn't seem to work. IS tehre an easy way to do this? I thought there' might be some kind of 'import existing code' thing in Eclipse but I can find it. How can I do this? Do I re-create the folder structure and just add the existing files one a time?
Thanks much for any help
something like 'create project from existing source'?
http://www.stanford.edu/class/cs108/JavaTools/eclipse-guide/
if the existing code is not structured well, you are either going to have to heavily configure your project sources, or just change the project structure.
File -> new
Than select general->folder.
To make developing easier in eclipse i recommend some refactoring to the project.
create a new eclipse project using the parent folder as the home.
every folder that's the root of a hierarchy of java classes becomes a folder in the "source" tab (either on creation, or add through "project->properties").
every jar (at least the ones he's using, there may be extras) gets added in the project->properties libraries tab.
This is assuming that all of the hierarchies belong together and that the thing isn't structured to build little sub-projects out of pieces of the hierarchy. If there's a build file for this thing you might want to be sure that if the build file is doing that you're building things appropriately.
File->Import->General->Existing Projects into Workspace
OR
File->New->Java Project
This will create a sample java project for you. You can add the files appropriately.
Below is an example of a j2ee Project:
http://java.sun.com/blueprints/code/projectconventions.html
If C:\Workspace is the folder you are using as the workspace and you have your existing project placed as "C:\Workspace\ExistingProject"
Open Eclipse Got to File->New Project
Select the type of Project you want to create Use the name as "ExistingProject" for the project and click Finish or complete the remaining steps of project creation wizard normally.
Internally a .project file would be created in the ExistingProject folder and a .metadata folder would be generated under Workspace folder.
If you want to place the ExistingProject not under the workspace u follow the same steps.
There's 2 possibilities:
Import project from file system:
Create a blank Eclipse Project.
Then select File -> Import -> General -> File System. Select project, and point it to your created project.
Importing from CVS
Goto File -> Import -> CVS -> Project from CVS
Enter your CVS Host, Repository Path, Username and Password, and click next,....
Add what you need and click next (follow the instructions) until you're satisfied and click finish.
Hope this helps.
A simple tutorial that incorporates my 1st option and commmits it to CVS: http://thedesignspace.net/MT2archives/000662.html
Two options:
Maven - highly recommended but rather read this: http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html than have me re-write it here. Maven might seem like more effort up front but it pays for itself a hundred times over during the course of even a simple project.
Do it yourself (assuming Helios):
Move the source code Java files to ~/development/MyProject/src/java. Move the jars to ~/development/MyProject/resources.
In Eclipse, File > New > Java Project. Type in your project name.
Untick "Use default location" and browse to ~/development/MyProject.
Select src/java as your source folder (if Eclipse doesn't pick it up automatically).
Finish.
Then, for each error, you will need to find the corresponding JAR and add it as a library to your classpath in the project properties.
The important thing to bear in mind is that Eclipse is not like Visual Studio - you cannot easily just edit one file at a time and that is not what it is designed for. People can get frustrated with Eclipse after working with VS but if you just allow it to do things the way it wants you, your life will be much easier.
trick is finding the root folder. Generally, developers use the following:
project root
-- src
-- bin
at least, what's what Eclipse does by default. There are other ways it can be organized as Maven uses the following:
project root
-- src
-- -- main
-- -- -- java
etc...
More info on how Maven standardizes here:
That said, finding out how the source is organized shouldn't be too hard. Open up one of the .java files and look for the line at the top that starts with "package ". Should be something like this:
package com.somecompany.client.utils
Note, that's just an example, it won't be that exactly although it should start with "package". The value after package represents the path that the file should be in relative to the root of the source folder.
source
folder/com/somecompany/client/utils
So, if you follow the default way that Eclipse organizes things, it should look look like this:
project root
-- src
-- -- com
-- -- -- somecompany
-- -- -- -- client
... etc
SO, as other people have mentioned, you'll import from existing filesystem, point to the folder at the project root. You may need to configure it to point to "src" folder as a source folder. You may also need to import those .jar files into your project as well.
Good luck

Categories

Resources