Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

We value code quality as much as you do. That's why, to help ensure quality and consistency across the Seam 3 project, we've established some guidelines that range from code formatting to testing. Refer to the guidelines laid out here when working on Seam 3.

Please know that the purpose of this document is to to serve as a guide (especially when it's 3am or the weekend and you aren't sure which way to go), rather than dictate. It's also an open book. If we're missing something, gone too far or you have a differing opinion, let's talk about it on the mailinglist or forums.

Process

  • Coordinate with the module lead before contributing to a module for the first time (even if you are a Seam committer or lead of another module)
  • POM file changes should be provided as patches to the module lead

License

  • Include the license file in the root of your module (feel free to steal it from another module)
  • Add the license header at the top of all Java and XML files (ASL 2.0). The license headers can be found at Seam Licensing.

Commit message

  • Use [ISSUE-###] format to get JIRA integration in commit messages on github.com

Code

  • All code must be Java 6 compatible. Hudson jobs will run with Java 6 to ensure this.
  • Format Java code using the JBoss Community formatting profile (IDE configurations)
  • Format XML source using the following settings (Eclipse doesn't have a profile for this)
    1. Indent using spaces
    2. Indentation size = 4
    3. Line width = 128
  • Use JBoss Logging 3 (bundled with Seam Solder) for logging (you can use the @Inject Logger provided by Seam Solder to make things easier); type-safe loggers are preferred
  • CDI annotations should not be used after the access modifier, but rather before e.g.
@Model
public class SampleBean { ... }
  • Fields should be private, including injection points; this follows good OO encapsulation practice; use getters/setters for extension
    it's also ideal if the component is going to be proxied
@Inject
private Messages messages;
  • Immutable classes make for more performant, easier to debug and threadsafe code, so you should strongly consider making all fields final and using constructor injection
  • Avoid inline blocks; we do not get charged per line, so there is no reason to be overly terse; go for readability
  • Write JavaDocs with usage scenarios (code samples!) for public-facing APIs (types and methods) and brief comments (dev-to-dev notes) for implementation
  • Create tests using JUnit 4.8 and, for integration tests, Arquillian; every module should have them!
  • Extension classes should be public and have a public constructor for maximum portability
  • API classes (including interceptor and decorators) should always be organized along functional lines. For example JMS API classes could go in org.jboss.seam.jms.publish or org.jboss.seam.jms.subscribe.
  • Interceptors and decorators class names should end with the word Interceptor or Decorator respectively e.g. TopicIntercptor
  • Interceptor extensions should always report an info-level log statement (or add a definition error if critical) that they have used an annotation requiring a currently disabled @Interceptor if the interceptor is not enabled. A utility method in Solder will be provided for this. https://jira.jboss.org/jira/browse/WELDX-91
  • Decorator extensions should always report an info-level log statement (or add a definition error if critical) that they have used an annotation requiring a currently disabled @Decorator. A utility method in Solder will be provided for this. https://jira.jboss.org/jira/browse/WELDX-91
  • Resources should only be loaded from the classpath using the ResourceProvider in Solder
  • Make sure you place tests in a subpackage of your main code packages, conventionally we use a sub-package called test. For example org.jboss.seam.jms.test.subscribe
  • AnnotationLiteral class should be immutable (set values using constructor)
  • In framework code, do a full class for an AnnotationLiteral, don't just instantiate inline (though inlining AnnotationLiteral instances is fine for tests)
  • Annotation literals should be in same package as annotation
    Seam Solder has a special literal package because those are annotation literals for annotations in the CDI API (which don't have annotation literals defined)
  • Annotation literals should be in the module's API if the annotation is in the module's API
  • [s-webfragname] If a module has a web-fragment.xml, it should include the <name> element with a value in the pattern SeamModule, where Module is the capitalized name of the module

Bean definition

  • Bean names should be qualified with the prefix org.jboss.seam. (e.g., #{org.jboss.seam.identity}, #{org.jboss.seam.messages}, etc). Note that Seam 3 will provide an extension allowing long names to be aliased to short names.
  • Always use declarative configuration (xml) rather than programmatic configuration to add beans etc. This allows tooling to understand your additional beans.

Architecture

  • Static instance calls within methods must be avoided; injection must used instead to make testing easier
  • View layer specific functionality for a module belongs in the view layer module for that view layer. (For example, JSF specific controls for Seam Security go into the Faces module).
  • Follow the Weld Log and Exception Message Guidelines for adding logging messages.
    TODO We need to port the infrastructure for this to Weld Extensions until JBoss Logging 3 is available. https://jira.jboss.org/jira/browse/WELDX-92
  • Qualify common types for internal use to avoid conflicts with types in the developer's application
  • Document common types that only have the @Default qualifier which your module is providing (e.g., java.lang.Locale, javax.persistence.PersistenceContext, etc)

Reference documentation

  • Follow the reference documentation style guide
  • Prefix your chapter id tags with the name of your module (e.g., security-introduction)
  • Prefix your docbook files with the name of your module (e.g., security-introduction.xml)
  • Prefix your chapter titles with the name of your module (e.g., Seam Security - Introduction)
  • If you add a new chapter to your module documentation (or rename an existing one), create a pull request to add it to the master.xml for the bundled documentation.

Maven and artifact management

  • [s-apiscope] All Java EE APIs (CDI, Servlet, JSF, JTA, etc) should be specified with the scope provided
  • Versions of all dependencies should be specified in the dependency management section of the seam-bom or seam-parent
  • If you need a plugin that doesn't have it's version specified in seam-parent:
    1. define it in the dependencyManagement section of your module's parent POM
    2. file a Task in SEAM requesting it to be added
  • Modules should use the groupId org.jboss.seam.[module], where [module] is the name of the module directory
  • Release versions should follow the pattern 3.x.y.Qualifier[n], including the Maven artifact version. Please refer to the JBoss Project Versioning Guidelines for details.
  • The build should use Maven 3.
  • You should mark a dependency as optional unless you think at least 80% of users are going to need that dependency -- in other words, non-optional dependencies should only be those which none of the code will operate without.
  • If you have multiple distinct usages for your module (e.g. consumers of the Drools module might just be interested in DroolsFlow, and not Drools Fusion), then consider creating stack POMs which define the dependencies for each usage. Each stack POM is a separate maven module, and should be placed in the stacks/<usage> directory.