7

We're trying to plan how to mash together a build server for our shiny new Java backend. We use a lot of JAXB XSD code generation and I was getting into a heated argument with whoever cared that the build server should:

  1. Delete JAXB created structures that were checked in.
  2. Generate the code from XSD's.
  3. Use code generated from those XSD's.

Everyone else thought that it made more sense to just use the code they checked in (we check in the code generated from the XSD because Eclipse pretty much forces you to do this as far as I can tell).

My only stale argument is in my reading of the Joel test is that making the build in one step means generating from the source code and the source code is not the Java source, but the XSD's because if you're messing around with the generated code you're gonna get pinched eventually.

So, given that we all agree (you may not agree) we should probably be checking in our generate Java files, should we use them to generate our code or should we generate it using the XSD's?

7
  • This is a good question that I want to ask as well. The way I would do it is to generate the jaxb by hands from the XSD and check in the generated code. I would treat the XSD as more of a documentation than the code itself even though it is true that the XSD generates the code.
    – InformedA
    Commented Jun 11, 2014 at 17:50
  • @randomA but you still don't touch the generated code right? Commented Jun 11, 2014 at 18:56
  • 1
    Why does "Eclipse force you to check in generated code"? We also use JAXB to create code from XSDs (using the mojo.codehaus.org/jaxb2-maven-plugin ) during the Maven build, and Eclipse is quite happy with that. You only need to manually add the folder under target/ with the generated code to Eclipse's "build path".
    – sleske
    Commented Jun 11, 2014 at 23:17
  • @Peter Turner Previously no, but now I touched the code a lot, I move to use the jaxb classes as both XML marshaling means and JPA. Lot of JPA annotations on many of the JAXB classes. As I said, it gets to the point where the XSD is more of a documentation, and outside/internal clients of the project can take advantage of the XSD generation tools without having out jaxb classes. Not sure if using both JPA and Jaxb like this would be against any best practice or not.
    – InformedA
    Commented Jun 12, 2014 at 3:01
  • I have a curious question though, where do the XSD come from? In my previous project, we consume the XML produced by other vendors, so we need their XSD or we create ones modeling their XML and documentation. In your case, does your project generate the JAXB objects and XML for other team to use, or you consume the XML produced by others?
    – InformedA
    Commented Jun 12, 2014 at 3:17

2 Answers 2

6

We have a similar situation here, but the schemas don't change that often so the Java doesn't need to be regenerated very often.

The way we deal with it is to create a new Maven project with just the schema files as source and generate Java code from that. We then deploy the generated Java as a jar to a local Nexus repository, but the only things that go into source control are the POM file, schema files, and any other necessary files (such as binding files). Any projects that require the generated Java get it as a dependency, from Nexus.

When the schema does change, the changes are checked in to source control, a new jar is generated and deployed to Nexus. Any projects that require the new version can simply update the dependencies to use the new version number.

The build server doesn't have to generate anything and the libraries are available for all teams to use, as dependencies in their own projects.

Our motivation to do it this way was that often many other teams need the generated Java for independent applications, and that once the schemas stabilize, they usually stay stable and don't need to be regenerated with every build/release.

6
  • That's good to know. Could you describe how to implement this strategy for a team that doesn't use Maven or Nexus.
    – InformedA
    Commented Jun 11, 2014 at 18:22
  • My problem is that we update the schemas all the time, you think that would change the way you do things? Commented Jun 11, 2014 at 18:55
  • @PeterTurner: I'm not sure... I think as long as we communicated the information about when new versions were released, and what was in them, this process would still work. But we don't have such frequent schema changes/releases, so it's hard to say. Commented Jun 11, 2014 at 18:57
  • @randomA: Before we used Maven and Nexus, schema files and generated source files and compiled jar files all got checked in to the project that hosted them, and jar files checked in on any other project that depended on them. It was a mess because not all developers were very careful to be sure they checked in changes to schema files, Java files, and jar files at the same time. The problems that resulted when things went wrong were some of the motivating factors to move to Maven (and Maven has improved the situation). Commented Jun 11, 2014 at 19:02
  • @FrustratedWithFormsDesigner So Maven is the key here. Currently, I keep the jaxb (which happens to be hand-crafted because I also annotate JPA on them to be used as DTO) in separate project/module. The other modules would checkout the JAXB/JPA project and have a reference to that project (we use Eclipse) I haven't moved the project into some serious state yet, so currently it is still using the built-in builders from Eclipse. Anyway, it's always good to know the current release engineering best practice to build software.
    – InformedA
    Commented Jun 12, 2014 at 2:56
4

Generated files shouldn't be checked into source code control (related: P.SE: Do I check generated code in to source control or not? SO Should I store generated code in source control). The code generated by jaxb certainly falls into this category.

The logic falls much the same reason you don't check in object files into source code control or the final build itself. They are the programatic output of some other process.

The contents of source code control should be enough to do a build from any given point in time. This may include the .xsd as part of the contract you are given for the API (just as one would check in .h files for a library in the C world).

Having generated source in source code control leads to the temptation to tweak it and it becomes something that you can't generate again. Someone else can't take jaxb and generate the same thing.

Generated source also runs up against the DRY principle. The necessary information to build it is in the .xsd and the build step. Adding the class files that are generated is another copy of this information with no added value.

From the two above points, realize that changing the generated source means (while necessary sometimes) means that the source code no longer matches the definition - it doesn't match the .xsd (or if dealing with a grammar, the source doesn't match the language definition anymore). Consider the nightmare when the application is ported from one language to another and you generate the source from the .xsd and the functionality of the generated code doesn't match that of the generated (and tweaked) code.

Sometimes, the generated source can be very large to the point of something prohibitively expensive to put into source code control. Anecdote: Apache Axis once generated a 4 megabyte .java file for me (yes, 4 megabytes of text) - I really didn't want to have that be something sitting in the source tree (most IDEs freaked out about something that massive).

So no, don't check in generated source. You should only have what you need to do a build and the steps to do that build.

1
  • I was going to -1 this answer because it just refutes the premises but since I so wholeheartedly agree with you, I'd rather just -2 everyone who checks in generated code. Commented Jun 12, 2014 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.