Skip to content

Repository files navigation

jcodemodel

Sonatype Central javadoc

If this project saved you some time or made your day a little easier, a star would mean a lot — it helps others find it too.

This project provides modeling and exporting java source code at java runtime, either in a pre-processing phase or to access them using a dynamic Classloader.

It is a fork of the com.sun.codemodel 2.7-SNAPSHOT.

The classes in this project use a different package name com.helger.jcodemodel to avoid conflicts with other com.sun.codemodel instances that might be floating around in the classpath. That of course implies, that this artefact cannot directly be used with JAXB, since the configuration of this would be very tricky.

Links and doc

Maven usage

Add the following to your pom.xml to use this artifact (where x.y.z denotes the version):

<dependency>
  <groupId>com.helger</groupId>
  <artifactId>jcodemodel</artifactId>
  <version>x.y.z</version>
</dependency>

News and noteworthy

v4.4.1 - work in progress

  • JOp.EPrecedence derives the binding strength from the declaration order (ordinal ()) again, instead of from an explicitly assigned level. EPrecedence.level () was removed
  • Fixed JOp.EPrecedence.LAMBDA binding as tight as ASSIGNMENT - a lambda binds looser, because a -> v = a is a -> (v = a). See #195 - thx @glelouet
  • Fixed the second operand of the ternary operator losing its parentheses in the ALWAYS and NOTOKEN strategies. See #195 - thx @glelouet

v4.4.0 - 2026-09-10

  • Expressions no longer surround themselves with parentheses - parentheses are only printed where the Java syntax requires them, so Math.sqrt (((x*x)+(y*y))) is now emitted as Math.sqrt (x*x + y*y). The new formatter setting parentheses.global selects the strategy: REQUIRED (default), NOTOKEN or ALWAYS. See #183 - thx @glelouet
  • Added IJGenerable.operatorPrecedence () returning the new enum JOp.EPrecedence, which carries the binding strength and the associativity of an operator. JOp.needsParentheses (...) and the new enum JOp.ESide decide whether a single operand has to be grouped
  • The unary, binary and ternary operators are now modelled by the new enums JOpUnary.EUnaryOp, JOpBinary.EBinaryOp and JOpTernary.ETernaryOp instead of plain strings
  • Removed JOpUnaryTight - JOp.preincr, JOp.postincr, JOp.predecr and JOp.postdecr now return JOpUnary
  • Removed JOp.hasTopOp (IJExpression) - the test expression of if, while, do and switch is now always parenthesized
  • The formatter no longer emits a space next to an already existing one, so case 0 : is now case 0:, return 10; is now return 10; and case 0, 2 -> is now case 0, 2 ->
  • Added IJFormatter.printNoSpace (String) for tokens that must stay attached to the previous one. A postfix operator now uses it, so a ++ is emitted as a++
  • Added the new package literals with EIntegerBase, IntegerRepresentation and AIntegerRepresented to define how int and long literals are emitted: base (binary, decimal, hexadecimal or octal), padding, _ separators, positive sign and prefix/body/suffix casing. The predefined representations BIN, BIN8, DEC, HEX and OCT are available; the default output is unchanged plain decimal. See #181 and #182 - thx @glelouet
  • JAtomInt and JAtomLong extend the new class AIntegerRepresented and offer a fluent API to select the representation per instance: binary (), decimal (), hexadecimal (), octal (), padding (int), separateEvery (int), separatorSize (int) and positiveSign (boolean). See #188 - thx @glelouet
  • IllegalStateException and IllegalArgumentException are thrown instead of the generic RuntimeException. See #185 and #187 - thx @glelouet
  • Also fixes the plugin not trying to fetch the source as an url, and showing errors when no error happened.
  • Also fixes the plugin silently skipping when the source could not be loaded.
  • Maven plugin: the data and the source parameters are now both applied, instead of data superseeding source. The generators receive the new ISourcedInputStream, that keeps the source an inputstream was created from. See #186 and #190 - thx @glelouet
  • Maven plugin: the source parameter may now also point to a directory - all contained files are then processed one after the other, optionally limited by the new sourcesFilter parameter. See #184 - thx @glelouet
  • Maven plugin: the source files are opened one at a time and always closed, even if the generation fails
  • Maven plugin: directories are no longer skipped by sourcesFilter - the filter applies to the files only, as documented
  • Maven plugin: symbolic link loops inside a source directory no longer lead to an endless recursion
  • Maven plugin: the generator is now always configured, so that it gets its default parameters even if no params are set
  • Maven plugin: the goal may now also be invoked with the short prefix jcm, as in mvn jcm:generate-source, instead of jcodemodel. The Maven help output of the mojo and of all its parameters was reworked. See #194 - thx @glelouet
  • Maven plugin: the String parameters are now tested for blankness instead of emptiness, so a whitespace only value is treated as "not set". See #194 - thx @glelouet
  • Maven plugin: the generator is now also invoked if neither source nor data is configured - it then receives ISourcedInputStream.NULL instead of nothing. See #193 - thx @glelouet
  • Generators that ignore their source now log a warning instead of silently discarding it. See #193 - thx @glelouet
  • CSV generator: the source is now read as UTF-8 by default, instead of the platform default charset. Use the new charset parameter to change it
  • CSV generator: the field_sep parameter is now used as a literal separator and no longer as a regular expression
  • CSV generator: a line containing only separators no longer throws an ArrayIndexOutOfBoundsException
  • CSV generator: the concrete.list, concrete.map and concrete.set parameters are now taken into account
  • CSV and JSON generators: a source without inputstream is handled as an empty source instead of throwing a NullPointerException
  • JSON generator: large sources no longer lead to a StackOverflowError when collecting the records
  • Flat structure generators: the classes referenced by the source are no longer initialized when they are resolved
  • Extended the documentation on how to write own generators. See #189 - thx @glelouet

v4.3.0 - 2026-07-24

  • Naming a class var now throws an exception, as var is no longer a valid type identifier (Var is still allowed). See #180 - thx @glelouet
  • Added support for pattern matching variables via new class JPatternVar in the vars package. See #169 and #170 - thx @glelouet
  • Started moving JFieldVar into the vars package. See #172 and #175 - thx @glelouet
  • Renamed the expression package to expressions (affects JArrayInit and JInstanceOfVar). See #170 - thx @glelouet
  • Fixed the final modifier detection in JMethod.param (...) and JMethod.varParam (...) (used | instead of &). See #169 - thx @glelouet
  • Added support for switch expressions (Java 14+) via new classes JSwitchExpression, JYield and arrow-style cases. See #144 - thx @glelouet
  • Added support for pattern matching with instanceof via new class JInstanceOfVar, invoked through JExpr.instanceOf (...). See #162 - thx @glelouet
  • Added support for the sealed and non-sealed modifiers and the permits clause on JDefinedClass. See #150 - thx @glelouet
  • Added support for local variable type inference (var); JVar no longer requires an explicit type. See #161 - thx @glelouet
  • Added the lazy initialization pattern via new class JLazy. See #160 - thx @glelouet
  • Added a concise try-with-resources syntax. See #142 - thx @glelouet
  • Added new interface IJModified and the emod (EMod...) API (with new enum EMod), implemented by JMods, JDefinedClass, JVar, JFieldVar and JMethod. See #155 - thx @glelouet
  • Added configurable formatter settings via FormatterSettings to control indentation and line wrapping. See #163 - thx @glelouet
  • Added JCMWriter.setJavaFeature (int) to target a specific Java feature version; features requiring a higher level may be replaced with fallback code. See #143
  • Fixed text block (JTextBlock) indentation handling. See #148 and #158 - thx @glelouet

v4.2.1 - 2026-05-29

  • Added support for annotations with parameters on type annotations and fixed @since tags. See #130 - thx @joelittlejohn
  • Added support for Java text blocks via #145 and #147, including a keepWhiteSpaces option - thx @glelouet
  • Generated test sources now carry an @Generated annotation #149 - thx @glelouet
  • Added proper license headers to the generated/javatests sources #139 - thx @glelouet

v4.2.0 - 2026-05-13

  • Removed OSGI bundling
  • Added support for Java record types. Fixes #98 via #126 - thx @joelittlejohn
  • Added support for annotation target TYPE_USE. Fixes #50 via #127 - thx @joelittlejohn
  • Added JDefinedClass.isRecord () and a mutable accessor recordComponentsMutable (); recordComponents () now returns an immutable list
  • Added JExpr.ref (JRecordComponent) and JExpr.refthis (JRecordComponent) for nicer record component references
  • Added JBlock._throw (AbstractJClass, IJExpression...) overload for throwing an exception with constructor arguments
  • Fixed JavaDoc reference to use JCMWriter instead of the deprecated cm.build (...). See #135

v4.1.0 - 2025-11-16

  • Updated to ph-commons 12.1.0
  • Using JSpecify annotations
  • Added Maven plugin to generate Java code from CSV, JSON or YAML. Thanks a million to @glelouet for providing all of the great work

v4.0.0 - 2025-08-25

  • Requires Java 17 as the minimum version
  • Using ph-commons as a compile dependency for common stuff
  • Moved all exceptions to exceptions package
  • Included [PR #96]](#96) from @glelouet on copying the whole JCodeModel

v3.4.1 - 2022-01-20

  • Extended JDefinedClass to make enum constants accessible

v3.4.0 - 2020-05-25

  • Added special top-level construct JResourceDir to represent pure resource directories (issue #74 from @guiguilechat)
  • Added new class JCodeModelException as the base class for JClassAlreadyExistsException and the new class JResourceAlreadyExistsException
  • Existing APIs were changed to throw JCodeModelException instead of JClassAlreadyExistsException
  • JCNameUtilities.getFullName works with classes in the default package
  • Extended JCodeModel with (get|set)FileSystemConvention to make the creation more flexible (also issue #74 from @guiguilechat)
  • Added mutable overloads to methods that only return an unmodifiable collection (issue #86)
  • Fixed an issue with generating generics from anonymous classes (issue #84)

v3.3.0 - 2019-11-24

  • Added check for package names so that no invalid package names can be created (issue #70 from @guiguilechat)
  • Added check to avoid creating classes existing in the "java.lang" package (issue #71 from @guiguilechat)
  • JLambdaMethodRef now works with arbitrary expressions as the left hand side

v3.2.4 - 2019-07-15

  • Made class JavaUnicodeEscapeWriter publicly accessible
  • Extended enum constant ref API (issue #68 from @guiguilechat)

v3.2.3 - 2019-03-31

  • Extended JTryBlock API to have more control.
  • Added support for try-with-resources support (issue #67 from @gmcfall)

v3.2.2 - 2019-02-25

  • Using jsr305 instead of annotations in POM (issue #66 from @jjYBdx4IL)

v3.2.1 - 2019-01-23

  • Added var as reserved word
  • Made JReturn constructor public
  • Added JInvocation._this static method
  • Added IJExpression.castTo method
  • Added support to create final variables in for each loops
  • JExpr.dotClass now takes AbstractJType and not just AbstractJClass
  • Made constructors of subclasses of IJStatement public
  • No line breaks for annotations to parameters
  • Put each method parameter on a separate line if more than 3 parameters are present

v3.2.0 - 2018-10-20

  • Introduced class JCMWriter that should be used to emit the outgoing Java files. This replaces codemodel.build and offers a more consistent API. Most existing method remain existing and deprecated and just forward to JCMWriter.
    • Instead of cm.build (...) use new JCMWriter (cm).build (...)
  • Extracted IJFormatter interface for better separation of concerns. JFormatter was moved to a sub-package
  • ProgressCodeWriter no longer needs an explicit PrintStream but a ProgressCodeWriter.IProgressTracker instead.
  • Default charset for Java classes is now UTF-8.
  • Added new JAnnotationUse method overloads that automatically pass value as the annotation parameter name (issue #64)

v3.1.0 - 2018-08-22

  • Added AbstractJType._new()
  • Change return types of special JBlock methods to void to avoid chaining (issue #62) - incompatible change!
  • Added new JExpr.invokeThis and JExpr.invokeSuper static methods

v3.0.3 - 2018-06-12

  • Improved API access to inner classes (issue #60)
  • Changed order of emitted modifiers (final static -> static final)
  • Flush needed when writing resources fixed (issue #61 from @fbaro)

v3.0.2 - 2018-04-11

  • Fixed method resolution using direct class references (issue #58)
  • Added some additional JInvocation.arg... sanity methods
  • Enum constant argument list is now accessible

v3.0.1 - 2017-10-25

  • Added explicit support for invoking super - thx to @heruan for pointing this out
  • Added possibility to create a lambda reference from an invocation (issue #56 and PR #57 from @heruan)

v3.0.0 - 2017-08-06

  • Requires Java 8
  • Reworked #41 so that it is finally working in all cases
  • Add option for classes to not be imported (issue #51)
  • Fixed extra semicolon on Lambdas (issue #53)

v2.8.6 2016-07-19

v2.8.5 - 2016-05-13

  • improved comment handling (issue #47)
  • improved API checks (issue #45)
  • extended API (issue #46)

v2.8.4 - 2016-04-25

  • Enum values in switch statements are no longer fully qualified (issue #41)
  • fixed generation of narrowed classes without parameters (as in HashMap<>)
  • added support for strictfp keyword.

v2.8.3 - 2016-02-26

  • Added support for single line comments in blocks
  • improved generation of Lambdas

v2.8.2 - 2016-01-19

  • Customizable new line string and character set
  • extensions by @sviperll

v2.8.1 - 2015-12-03

  • Extensions by @sviperll

v2.8.0 - 2015-10-12

  • Requires Java 1.6
  • fixed potential double imports
  • added virtual blocks
  • integrated sviperll's metachicory

v2.7.11 - 2015-09-24

  • Bugfix release
  • removed half done CSE implementation (issue #18)
  • improved handling of directClasses
  • added enumConstantReference

v2.7.10 - 2015-06-30

  • Synchronized block added
  • initial support for lambda expressions

v2.7.9 - 2015-03-19

  • Minor extensions for error types

v2.7.8 - 2015-02-05

  • Enum constants for annotation parameters

v2.7.7 - 2014-09-17

  • mainly API extensions

v2.7.6 - 2014-09-02

  • Extended annotation parameter handling API

v2.7.5 - 2014-08-14

  • Support for multiple boundaries added (like T extends AnyClass & Serializable)

v2.7.4 - 2014-06-12

  • Bugfix release

v2.7.3 - 2014-05-23

  • Bugfix release

v2.7.2 - 2014-05-21

  • now on Maven Central

v2.7.1 - 2014-05-19

  • now as OSGi bundle

v2.7.0 - 2014-05-16

  • API extensions

v2.6.4 - 2014-04-10

2013-09-23


My personal Coding Styleguide | It is appreciated if you star the GitHub project if you like it.

About

A heavily extended fork of the com.sun.codemodel (from 2013/09)

Topics

Resources

Code of conduct

Contributing

Stars

100 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages