Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

and many more ....

Featured FREE Whitepapers

What's New Here?


You Do Need Independent Technical Reviews!

Do you have a team of brilliant and enthusiastic programmers? Of course! You’ve carefully chosen them from a hundred candidates! Are they passionate about the product? Absolutely! They use cutting-edge technologies, never sleep, and hardly eat or drink anything except coffee! Do they believe in your business success? No doubts about it; they live and breathe all those features, releases, continuous delivery, user experience, etc. Are you sure they are developing the product correctly? Well, yes, you’re pretty sure; why wouldn’t they? … Does this sound familiar? I can’t count how many times I’ve heard these stories told by startup founders. Most of them are in love with their teams … until that day when it’s time to hire a new one. There could be many possible reasons for such a fiasco, but one of them is a lack of regular, systematic, and independent technical reviews. Nothing demotivates a development team more than a lack of attention to their deliverables. On the other hand, a regular reconciliation of their results and your quality expectations is one of the key factors that will guarantee technical success for your startup. Below I summarize my experience with organizing such technical reviews. An independent review is when you ask someone outside of your team to look at your source code and other technical resources and give you an objective opinion about them. Every modern software team should also use internal code reviews, which is is something else entirely. An internal review occurs when one programmer shows his code to other peers on the team and asks their opinion. This usually happens as a daily activity and has nothing to do with independent reviews. An independent review is performed by a programmer who knows nothing about your team. He comes on board, checks out the code from your repository, spends a few hours (or days) looking at it and trying to understand what it does. Then, he tells you what is wrong and where. He explains how he would do it better, where he would change it, and what he would do instead. Then, you pay him and he leaves. You may never see him again, but his conclusions and suggestions help you check the reality of your code and evaluate how your team is really doing. We, at, do independent reviews with every project of ours, and this is a list of principles we use: Make Independent Reviews Systematic. This is the first and most important rule — organize such technical reviews regularly. Moreover, inform your team about the schedule, and let them be prepared for the reviews. Once a month is a good practice, according to my experience. Depending on your source code size, a full review should take from two to eight hours. Don’t spend more than eight hours; there is no point in going too deep into the code during independent reviews. Pay for Bugs Found. We always pay for bugs, not for the time spent finding them. We ask our reviewers to look at the code and report as many bugs as we think we need. For each bug, we pay 15 minutes for their time. In other words, we assume that a good reviewer can find and report approximately four problems in one hour. For example, a reviewer charges $150 per hour. We hire him and ask him to find and report the 20 most criticial issues he can discover. Our estimate is that he should spend five hours on this work. Thus, he will get $750 when we have 20 bugs in our tracking system reported by him. If he finds fewer, he gets proportionally less money. This payment schedule will help you focus your reviewer on the main objective of the review process — finding and reporting issues. There are no other goals. The only thing you’re interested in is knowing what the issues with your current technical solution are. That’s what you’re paying for. Hire the Best and Pay Well. My experience tells me that the position of an independent reviewer is a very important one. He is not just a programmer but more of an architect who is capable of looking at the solution from a very high level of abstraction, while at the same time paying a lot of attention to details; he should be very good at designing similar systems; he should know how to report a bug correctly and with enough detail; he should understand your business domain; etc. Besides all that, he should be well motivated to help you. You’re not hiring him for full-time work but rather just for a few-hour gig. My advice is to try to get the best guys, and pay them as much as they ask, usually over $100 per hour. Don’t negotiate, just pay. It’s just a few hundred dollars for you, but the effect of their contribution will be huge. Ask For and Expect Criticism. It is a very common mistake to ask a reviewer, “Do you like our code?” Don’t expect him to tell you how great your code is. This is not what you’re paying him for! You already have a full team of programmers for cheering you up; they can tell you a lot about the code they are creating and how awesome it is. You don’t want to hear this again from the reviewer. Instead, you want to know what is wrong and needs to be fixed. So your questions should sound like, “What problems do you think we should fix first?” Some reviewers will try to please you with positive comments, but ignore that flattery and bring them back to the main goal — bugs. The payment schedule explained above should help. Regularly Change Reviewers. Try not to use the same reviewer more than once on the same project (I mean the same code base). I believe the reason here is obvious, but let me re-iterate: You don’t need your reviewer to be nice to you and tell you how great your code is. You want him to be objective and focused on problems, not on bright sides. If you hire the same person again and again, psychologically you make him engaged to the source code. He’s seen it once; now he has to see it again. He already told you about some problem, and now he has to repeat it again. He won’t feel comfortable doing it. Instead, he will start feeling like a member of the team and will feel responsible for the source code and its mistakes. He, as any other team member, will start hiding issues instead of revealing them. Thus, for every independent technical review, get a new person. Be Polite and Honest With Your Team. Independent reviews can be rather offensive to your programmers. They may think that you don’t trust them. They may feel that you don’t respect them as technical specialists. They may even decide that you’re getting ready to fire them all and are currently looking for new people. This is a very possible and very destructive side effect of an independent review. How do you avoid it? I can’t give you universal advice, but the best suggestion I can give is this: be honest with them. Tell them that the quality of the product is critical for you and your business. Explain to them that the business is paying them for their work and that in order to keep paychecks coming, you have to stress quality control — regularly, objectively, independently, and honestly. In the end, if you manage to organize reviews as this article explains, the team will be very thankful to you. They will gain a lot of new ideas and thoughts from every review and will ask you to repeat them regularly. Review From Day One. Don’t wait until the end of the project! I’ve seen this mistake many times. Very often startup founders think that until the product is done and ready for the market, they shouldn’t distract their team. They think they should let the team work toward project milestones and take care of quality later, “when we have a million visitors per day”. This day will never come if you let your team run without control! Start conducting independent reviews from the moment your Git repository has its first file. Until the repository is big enough, you may only spend $300 once a month to receive an objective, independent opinion about its quality. Will this ruin your budget? Prohibit Discussions, and Ask for Formal Reporting. Don’t let your reviewers talk to the team. If you do, the entire idea of a review being independent falls apart. If a reviewer is able to ask informal questions and discuss your system design with your programmers, their answers will satisfy him, and he will move on. But you, the owner of the business, will stay exactly where you were before the review. The point of the review is not to make the reviewer happy. It is exactly the opposite. You want to make him confused! If he is confused, your design is wrong and he feels the need to report a bug. The source code should speak for itself, and it should be easy enough for a stranger (the reviewer) to understand how it works. If this is not the case, there is something wrong that should be fixed. Treat Any Question as a Bug. Don’t expect a review to produce any bugs in functionality, like “I click this button and the system crashes”. This will happen rarely, if ever. Your team is very good at discovering these issues and fixing them. Independent reviews are not about that kind of bugs. The main goal of an independent review is to discover bugs in the architecture and design. Your product may work, but its architecture may have serious design flaws that won’t allow you, for example, to handle exponential growth in web traffic. An independent reviewer will help you find those flaws and address them sooner than later. In order to get bugs of that kind from the reviewer, you should encourage him to report anything he doesn’t like — unmotivated use of a technology, lack of documentation, unclear purpose of a file, absence of a unit test, etc. Remember, the reviewer is not a member of your team and has his own ideas about the technologies you’re using and software development in general. You’re interested in matching his vision with your team’s. Then, you’re interested in fixing all critical mismatches. Review Everything, Not Just Source Code. Let your reviewer look at all technical resources you have, not just source code files (.java, .rb, .php, etc.) Give him access to the database schema, continuous integration panel, build environment, issue tracking system, plans and schedules, work agendas, uptime reports, deployment pipeline, production logs, customer bug reports, statistics, etc. Everything that could help him understand how your system works, and more importantly, where and how it breaks, is very useful. Don’t limit the reviewer to the source code only — this is simply not enough! Let him see the big picture, and you will get a much more detailed and professional report. Track How Inconsistencies Are Resolved. Once you get a report from the reviewer, make sure that the most important issues immediately get into your team’s backlog. Then, make sure they are addressed and closed. That doesn’t mean you should fix them all and listen to everything said by the reviewer. Definitely not! Your architect runs the show, not the reviewer. Your architect should decide what is right and what is wrong in the technical implementation of the product. But it’s important to make him resolve all concerns raised by the reviewer. Very often you will get answers like these from him: “We don’t care about it now”, “we won’t fix it until the next release”, or “he is wrong; we’re doing it better”. These answers are perfectly valid, but they have to be given (reviewers are people and they also make mistakes). The answers will help you, the founder, understand what your team is doing and how well they understand their business.Reference: You Do Need Independent Technical Reviews! from our JCG partner Yegor Bugayenko at the About Programming blog....

Why I Won’t Accept ANY Magic Number

One of the first things I like to establish in a new project is the use of tools like Checkstyle and Findbugs in order to codify some code guidelines and to avoid bugs that can be determined by static code analysis. Sooner or later with these tools one stumbles over a case where people have the feeling it is going to far. One such case is the check for Magic Numbers of Checkstyle. It will warn about any use of numeric literals except -1, 0, 1 and 2 that aren’t used to define a constant. Many developers have a problem with this check as one can see from the resulting code. I have seen code like this:   private static final int FOUR = 4; and also private static final int FOUR = 5; and my all time favorite (I’m not making this up!): firstname = rs.getString(1); lastname = rs.getString(2); city = rs.getString(2 + 1); zip = rs.getString(2 + 2); country = rs.getString(2 + 2 + 1); But there is a different case where the discussion comes up. It’s with obvious constants like 100 for converting fractions into percent values or 1024 for conversion between bytes and kibibytes. Some argue these aren’t magic numbers (or magic numbers but not as bad) because their meaning is obvious and they won’t change. I disagree and will vote to make them constants any time. Here is why:The meaning is NOT obvious. What does value * 100 mean? Is a fraction converted to percent? Is a length measured in meters, converted to centimeters? Or something multiplied by a rough approximation of g*g with g being the gravitational acceleration on earth? Or maybe I’m multiplying something with the size of an array, that happens to be 100. Can’t tell. A simple constant with a proper name will fix that. Ok, I do agree, many of these constants won’t change. But the purpose of defining constants (or methods, or classes) is not (only) to enable later change, but to make reading, understanding and reasoning more easy. So the question if a value might change in the future is completely irrelevant. (This one is the argument that I’m missing in most of the discussions) I just don’t want to think about it or have others think about it. I have seen dozens, probably hundreds of instances, where a properly named constant would have helped tremendously understanding a piece of code. And I have seen very few cases where it might have hurt readability and not a single one where it hurt badly. Therefore: just extract a constant and be done with it.Note: Just because it is a constant doesn’t mean it has to be public, or even a class level field. If it is used only in a single method a local variable is just fine.Reference: Why I Won’t Accept ANY Magic Number from our JCG partner Jens Schauder at the Schauderhaft blog....

Looking into the Java 9 Money and Currency API (JSR 354)

JSR 354 defines a new Java API for working with Money and Currencies, which is planned to be included in Java 9. In this post we will look at the current state of the reference implementation: JavaMoney. Like my post about the Java 8 Date/Time API this post will be mainly driven by code that shows the new API. But before we start, I want to quote a short section from the specification that pretty much sums up the motivation for this new API:   Monetary values are a key feature of many applications, yet the JDK provides little or no support. The existing java.util.Currency class is strictly a structure used for representing current ISO 4217 currencies, but not associated values or custom currencies. The JDK also provides no support for monetary arithmetic or currency conversion, nor for a standard value type to represent a monetary amount. If you use Maven, you can easily try the current state of the reference implementation by adding the following dependency to your project: <dependency>   <groupId>org.javamoney</groupId>   <artifactId>moneta</artifactId>   <version>0.9</version> </dependency> All specification classes and interfaces are located in the* package. We will start with the two core interfaces CurrencyUnit and MonetaryAmount. After that, we will look into exchange rates, currency conversion and formatting. CurrencyUnit and MonetaryAmount CurrencyUnit models a currency. CurrencyUnit is very similar to the existing java.util.Currency class, except it allows custom implementations. According to the specification it should be possible that java.util.Currency implements CurrencyUnit. CurrencyUnit instances can be obtained using the MonetaryCurrencies factory: // getting CurrencyUnits by currency code CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR"); CurrencyUnit usDollar = MonetaryCurrencies.getCurrency("USD");// getting CurrencyUnits by locale CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN); CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA); MontetaryAmount represents a concrete numeric representation of a monetary amount. A MonetaryAmount is always bound to a CurrencyUnit. Like CurrencyUnit, MonetaryAmount is an interface that supports different implementations. CurrencyUnit and MonetaryAmount implementations must be immutable, thread safe, serializable and comparable. // get MonetaryAmount from CurrencyUnit CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR"); MonetaryAmount fiveEuro = Money.of(5, euro);// get MonetaryAmount from currency code MonetaryAmount tenUsDollar = Money.of(10, "USD");// FastMoney is an alternative MonetaryAmount factory that focuses on performance MonetaryAmount sevenEuro = FastMoney.of(7, euro); Money and FastMoney are two MonetaryAmount implementations of JavaMoney. Money is the default implementation that stores number values using BigDecimal. FastMoney is an alternative implementation which stores amounts in long fields. According to the documentation  operations on FastMoney are 10-15 times faster compared to Money. However, FastMoney is limited by the size and precision of the long type. Please note that Money and FastMoney are implementation specific classes (located in org.javamoney.moneta.* instead of*). If you want to avoid implementation specific classes, you have to obtain a MonetaryAmountFactory to create a MonetaryAmount instance: MonetaryAmount specAmount = MonetaryAmounts.getDefaultAmountFactory()     .setNumber(123.45)     .setCurrency("USD")     .create(); Two MontetaryAmount instances are considered equal if the implementation classes, the currency units and the numeric values are equal: MonetaryAmount oneEuro = Money.of(1, MonetaryCurrencies.getCurrency("EUR")); boolean isEqual = oneEuro.equals(Money.of(1, "EUR")); // true boolean isEqualFast = oneEuro.equals(FastMoney.of(1, "EUR")); // false MonetaryAmount has various methods that allow accessing the assigned currency, the numeric amount, its precision and more: MonetaryAmount monetaryAmount = Money.of(123.45, euro); CurrencyUnit currency = monetaryAmount.getCurrency(); NumberValue numberValue = monetaryAmount.getNumber();int intValue = numberValue.intValue(); // 123 double doubleValue = numberValue.doubleValue(); // 123.45 long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100 long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45 int precision = numberValue.getPrecision(); // 5// NumberValue extends java.lang.Number.  // So we assign numberValue to a variable of type Number Number number = numberValue; Working with MonetaryAmounts Mathematical operations can be performed with MonetaryAmount: MonetaryAmount twelveEuro = fiveEuro.add(sevenEuro); // "EUR 12" MonetaryAmount twoEuro = sevenEuro.subtract(fiveEuro); // "EUR 2" MonetaryAmount sevenPointFiveEuro = fiveEuro.multiply(1.5); // "EUR 7.5"// MonetaryAmount can have a negative NumberValue MonetaryAmount minusTwoEuro = fiveEuro.subtract(sevenEuro); // "EUR -2"// some useful utility methods boolean greaterThan = sevenEuro.isGreaterThan(fiveEuro); // true boolean positive = sevenEuro.isPositive(); // true boolean zero = sevenEuro.isZero(); // false// Note that MonetaryAmounts need to have the same CurrencyUnit to do mathematical operations // this fails with: Currency mismatch: EUR/USD fiveEuro.add(tenUsDollar); Rounding is another important part when working with money. MonetaryAmounts can be rounded using a rounding operator: CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD"); MonetaryAmount dollars = Money.of(12.34567, usd); MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd); MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35 Here 12.3456 US Dollars are rounded with the default rounding for this currency. When working with collections of MonetaryAmounts, some nice utility methods for filtering, sorting and grouping are available. These methods can be used together with the Java 8 Stream API. Consider the following collection: List<MonetaryAmount> amounts = new ArrayList<>(); amounts.add(Money.of(2, "EUR")); amounts.add(Money.of(42, "USD")); amounts.add(Money.of(7, "USD")); amounts.add(Money.of(13.37, "JPY")); amounts.add(Money.of(18, "USD")); We can now filter amounts by CurrencyUnit: CurrencyUnit yen = MonetaryCurrencies.getCurrency("JPY"); CurrencyUnit dollar = MonetaryCurrencies.getCurrency("USD");// filter by currency, get only dollars // result is [USD 18, USD 7, USD 42] List<MonetaryAmount> onlyDollar =     .filter(MonetaryFunctions.isCurrency(dollar))     .collect(Collectors.toList());// filter by currency, get only dollars and yen // [USD 18, USD 7, JPY 13.37, USD 42] List<MonetaryAmount> onlyDollarAndYen =     .filter(MonetaryFunctions.isCurrency(dollar, yen))     .collect(Collectors.toList()); We can also filter out MonetaryAmounts smaller or greater than a specific threshold: MonetaryAmount tenDollar = Money.of(10, dollar);// [USD 42, USD 18] List<MonetaryAmount> greaterThanTenDollar =     .filter(MonetaryFunctions.isCurrency(dollar))     .filter(MonetaryFunctions.isGreaterThan(tenDollar))     .collect(Collectors.toList()); Sorting works in a similar way: // Sorting dollar values by number value // [USD 7, USD 18, USD 42] List<MonetaryAmount> sortedByAmount =     .sorted(MonetaryFunctions.sortNumber())     .collect(Collectors.toList());// Sorting by CurrencyUnit // [EUR 2, JPY 13.37, USD 42, USD 7, USD 18] List<MonetaryAmount> sortedByCurrencyUnit =     .sorted(MonetaryFunctions.sortCurrencyUnit())     .collect(Collectors.toList()); Grouping functions: // Grouping by CurrencyUnit // {USD=[USD 42, USD 7, USD 18], EUR=[EUR 2], JPY=[JPY 13.37]} Map<CurrencyUnit, List<MonetaryAmount>> groupedByCurrency =     .collect(MonetaryFunctions.groupByCurrencyUnit());// Grouping by summarizing MonetaryAmounts Map<CurrencyUnit, MonetarySummaryStatistics> summary =     .collect(MonetaryFunctions.groupBySummarizingMonetary()).get();// get summary for CurrencyUnit USD MonetarySummaryStatistics dollarSummary = summary.get(dollar); MonetaryAmount average = dollarSummary.getAverage(); // "USD 22.333333333333333333.." MonetaryAmount min = dollarSummary.getMin(); // "USD 7" MonetaryAmount max = dollarSummary.getMax(); // "USD 42" MonetaryAmount sum = dollarSummary.getSum(); // "USD 67" long count = dollarSummary.getCount(); // 3 MonetaryFunctions also provides reduction function that can be used to obtain the max, min and sum of a MonetaryAmount collection: List<MonetaryAmount> amounts = new ArrayList<>(); amounts.add(Money.of(10, "EUR")); amounts.add(Money.of(7.5, "EUR")); amounts.add(Money.of(12, "EUR"));Optional<MonetaryAmount> max =; // "EUR 7.5" Optional<MonetaryAmount> min =; // "EUR 12" Optional<MonetaryAmount> sum =; // "EUR 29.5" Custom MonetaryAmount operations MonetaryAmount provides a nice extension point called MonetaryOperator. MonetaryOperator is a functional interface that takes a MonetaryAmount as input and creates a new MonetaryAmount based on the input. // A monetary operator that returns 10% of the input MonetaryAmount // Implemented using Java 8 Lambdas MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {   BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);   BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));   return Money.of(tenPercent, amount.getCurrency()); };MonetaryAmount dollars = Money.of(12.34567, "USD");// apply tenPercentOperator to MonetaryAmount MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567 Some standard API features are implemented as MonetaryOperator. For example, the rounding features we saw above are implemented as MonetaryOperator. Exchange rates Currency exchange rates can be obtained using an ExchangeRateProvider. JavaMoney comes with multiple different ExchangeRateProvider implementations. The two most important implementations are ECBCurrentRateProvider and IMFRateProvider. ECBCurrentRateProvider queries the European Central Bank (ECB) data feed for getting current exchange rates while IMFRateProvider uses International Monetary Fund (IMF) conversion rates. // get the default ExchangeRateProvider (CompoundRateProvider) ExchangeRateProvider exchangeRateProvider = MonetaryConversions.getExchangeRateProvider();// get the names of the default provider chain // [IDENT, ECB, IMF, ECB-HIST] List<String> defaultProviderChain = MonetaryConversions.getDefaultProviderChain();// get a specific ExchangeRateProvider (here ECB) ExchangeRateProvider ecbExchangeRateProvider = MonetaryConversions.getExchangeRateProvider("ECB"); If no specific ExchangeRateProvider is requested a CompoundRateProvider will be returned. CompoundRateProvider delegates exchange rate requests to a chain of ExchangeRateProviders and returns the result from the first provider that returns an adequate result. // get the exchange rate from euro to us dollar ExchangeRate rate = exchangeRateProvider.getExchangeRate("EUR", "USD");NumberValue factor = rate.getFactor(); // 1.2537 (at time writing) CurrencyUnit baseCurrency = rate.getBaseCurrency(); // EUR CurrencyUnit targetCurrency = rate.getCurrency(); // USD Currency conversion Conversion between currencies is be done with CurrencyConversions that can be obtained from ExchangeRateProviders: // get the CurrencyConversion from the default provider chain CurrencyConversion dollarConversion = MonetaryConversions.getConversion("USD");// get the CurrencyConversion from a specific provider CurrencyConversion ecbDollarConversion = ecbExchangeRateProvider.getCurrencyConversion("USD");MonetaryAmount tenEuro = Money.of(10, "EUR");// convert 10 euro to us dollar  MonetaryAmount inDollar = tenEuro.with(dollarConversion); // "USD 12.537" (at the time writing) Note that CurrencyConversion implements MonetaryOperator. Like other operators it can be applied using MonetaryAmount.with(). Formatting and parsing MonetaryAmounts can be parsed/formatted from/to string using a MonetaryAmountFormat: // formatting by locale specific formats MonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMANY); MonetaryAmountFormat usFormat = MonetaryFormats.getAmountFormat(Locale.CANADA);MonetaryAmount amount = Money.of(12345.67, "USD");String usFormatted = usFormat.format(amount); // "USD12,345.67" String germanFormatted = germanFormat.format(amount); // 12.345,67 USD// A MonetaryAmountFormat can also be used to parse MonetaryAmounts from strings MonetaryAmount parsed = germanFormat.parse("12,4 USD"); With AmountFormatQueryBuilder custom formats can be created: // Creating a custom MonetaryAmountFormat MonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat(     AmountFormatQueryBuilder.of(Locale.US)         .set(CurrencyStyle.NAME)         .set("pattern", "00,00,00,00.00 ¤")         .build());// results in "00,01,23,45.67 US Dollar" String formatted = customFormat.format(amount); Note that the ¤ symbol (\u00A) is used as currency placeholder inside the pattern string. Summary We looked at many parts of the new Money and Currency API. The implementation already looks quite solid (but definitely needs some more documentation). I am looking forward to see this API in Java 9!You can find all the examples shown here on GitHub.Reference: Looking into the Java 9 Money and Currency API (JSR 354) from our JCG partner Michael Scharhag at the mscharhag, Programming and Stuff blog....

How is Java / JVM built ? Adopt OpenJDK is your answer!

Introduction & history As some of you may already know, starting with Java 7, OpenJDK is the Reference Implementation (RI) to Java. The below timeline gives you an idea about the history of OpenJDK:          See Adopt OpenJDK – the past present and future [1] for some more details. If you have wondered about the JDK or JRE binaries that you download from vendors like Oracle, Red Hat, etcetera, then the clue is that these all stem from OpenJDK. Each vendor then adds some extra artefacts that are not open source yet due to security, proprietary or other reasons. What is OpenJDK made of ? OpenJDK is made up of a number of repositories, namely corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn. Between OpenjJDK8 and OpenJDK9 there have been no new repositories introduced, but lots of new changes and restructuring, primarily due to Jigsaw – the modularisation of Java itself [2] [3] [4] [5].  How has Java the language and platform built over the years ? Java is built by bootstrapping an older (previous) version of Java – i.e. Java is built using Java itself as its building block. Where older components are put together to create a new component which in the next phase becomes the building block. A good example of bootstrapping can be found at Scheme from Scratch [6] or even on Wikipedia [7]. OpenJDK8 [8] is compiled and built using JDK7, similarly OpenJDK9 [9] is compiled and built using JDK8. In theory OpenJDK8 can be compiled using the images created from OpenJDK8, similarly for OpenJDK9 using OpenJDK9. Using a process called bootcycle images – a JDK image of OpenJDK is created and then using the same image, OpenJDK is compiled again, which can be accomplished using a make command option: $ make bootcycle-images       # Build images twice, second time with newly built JDK make offers a number of options under OpenJDK8 and OpenJDK9, you can build individual components or modules by naming them, i.e. $ make [component-name] | [module-name] or even run multiple build processes in parallel, i.e. $ make JOBS=<n>                 # Run <n> parallel make jobs Finally install the built artefact using the install option, i.e. $ make install Some myths busted OpenJDK or Hotspot to be more specific isn’t completely written in C/C++, a good part of the code-base is good ‘ole Java (see the composition figure above). So you don’t have to be a hard-core developer to contribute to Open JDK. Even the underlying C/C++ code code-base isn’t scary or daunting to look at. For example here is an extract of a code snippet from vm/memory/universe.cpp in the HotSpotrepo – [10]: . . . Universe::initialize_heap()if (UseParallelGC) { #ifndef SERIALGC Universe::_collectedHeap = new ParallelScavengeHeap(); #else // SERIALGC fatal("UseParallelGC not supported in this VM."); #endif // SERIALGC} else if (UseG1GC) { #ifndef SERIALGC G1CollectorPolicy* g1p = new G1CollectorPolicy(); G1CollectedHeap* g1h = new G1CollectedHeap(g1p); Universe::_collectedHeap = g1h; #else // SERIALGC fatal("UseG1GC not supported in java kernel vm."); #endif // SERIALGC} else { GenCollectorPolicy* gc_policy;if (UseSerialGC) { gc_policy = new MarkSweepPolicy(); } else if (UseConcMarkSweepGC) { #ifndef SERIALGC if (UseAdaptiveSizePolicy) { gc_policy = new ASConcurrentMarkSweepPolicy(); } else { gc_policy = new ConcurrentMarkSweepPolicy(); } #else // SERIALGC fatal("UseConcMarkSweepGC not supported in this VM."); #endif // SERIALGC } else { // default old generation gc_policy = new MarkSweepPolicy(); }Universe::_collectedHeap = new GenCollectedHeap(gc_policy); } . . . (please note that the above code snippet might have changed since published here) The things that appears clear from the above code-block are, we are looking at how pre-compiler notations are used to create Hotspot code that supports a certain type of GC i.e. Serial GC or Parallel GC. Also the type of GC policy is selected in the above code-block when one or more GC switches are toggled i.e. UseAdaptiveSizePolicy when enabled selects the Asynchronous Concurrent Mark and Sweep policy. In case of either Use Serial GC or Use Concurrent Mark Sweep GC are not selected, then the GC policy selected is Mark and Sweep policy. All of this and more is pretty clearly readable and verbose, and not just nicely formatted code that reads like English. Further commentary can be found in the section called Deep dive Hotspot stuff in the Adopt OpenJDK Intermediate & Advance experiences [11] document. Steps to build your own JDK or JRE Earlier we mentioned about JDK and JRE images – these are no longer only available to the big players in the Java world, you and I can build such images very easily. The steps for the process have been simplified, and for a quick start see the Adopt OpenJDK Getting Started Kit [12] and Adopt OpenJDK Intermediate & Advance experiences [11] documents. For detailed version of the same steps, please see the Adopt OpenJDK home page [13]. Basically building a JDK image from the OpenJDK code-base boils down to the below commands: (setup steps have been made brief and some commands omitted, see links above for exact steps) $ hg clone jdk8  (a)...OpenJDK8 or $ hg clone jdk9  (a)...OpenJDK9 $ ./                                    (b) $ bash configure                                      (c) $ make clean images                                   (d) (setup steps have been made brief and some commands omitted, see links above for exact steps) To explain what is happening at each of the steps above: (a) We clone the openjdk mercurial repo just like we would using git clone …. (b) Once we have step (a) completed, we change into the folder created, and run the command, which is equivalent to a git fetch or a git pull, since the step (a) only brings down base files and not all of the files and folders. (c) Here we run a script that checks for and creates the configuration needed to do the compile and build process (d) Once step (c) is success we perform a complete compile, build and create JDK and JRE images from the built artefacts As you can see these are dead-easy steps to follow to build an artefact or JDK/JRE images [step (a) needs to be run only once]. Benefitscontribute to the evolution and improvement of the Java the language & platform learn about the internals of the language and platform learn about the OS platform and other technologies whilst doing the above get involved in F/OSS projects stay on top the latest changes in the Java / JVM sphere knowledge and experience that helps professionally but also these are not readily available from other sources (i.e. books, training, work-experience, university courses, etcetera) advancement in career personal development (soft skills and networking)Contribute Join the Adopt OpenJDK [14] and Betterrev [15] projects and contribute by giving us feedback about everything Java including these projects. Join the Adoption Discuss mailing list and other OpenJDK related mailing lists to start with, these will keep you updated with latest progress and changes to OpenJDK. Fork any of the projects you see and submit changes via pull-requests. Thanks and support Adopt OpenJDK [14] and umbrella projects have been supported and progressed with help of JCP [21], the Openjdk team [22], JUGs like London Java Community [16], SouJava [17] and other JUGs in Brazil, a number of JUGs in Europe i.e. BGJUG (Bulgarian JUG) [18], BeJUG (Belgium JUG) [19], Macedonian JUG [20], and a number of other small JUGs. We hope in the coming time more JUGs and individuals would get involved. If you or your JUG wish to participate please get in touch.Reference: How is Java / JVM built ? Adopt OpenJDK is your answer! from our JCG partner Mani Sarkar at the Java Advent Calendar blog....

A True SQL Gem You Didn’t Know Yet: The EVERY() Aggregate Function

We’ve just added support for the EVERY() aggregate function (#1391) to jOOQ, and would like to take the opportunity of letting you know of this true SQL gem that can come in handy EVERY(now and then) (pun intended). Let’s assume we have four books in our table:             INSERT INTO book VALUES (1, 1, '1984'); INSERT INTO book VALUES (2, 1, 'Animal Farm'); INSERT INTO book VALUES (3, 2, 'O Alquimista'); INSERT INTO book VALUES (4, 2, 'Brida'); Now the question is: Is EVERY() ID lower than 10? We’ll ask: SELECT EVERY(id < 10) FROM book And the answer is: every ----- true Does EVERY() book for each author end with the letter ‘a’? We’ll ask: SELECT author_id, EVERY(title LIKE '%a') FROM book GROUP BY author_id And the answer is: author_id every ----------------- 1 false 2 true Wonderful! As with all aggregate functions, we can even use them as a window function! SELECT book.*, EVERY(title LIKE '%a') OVER (PARTITION BY author_id) FROM book Which will produce: id author_id title every ------------------------------------ 1 1 1984 false 2 1 Animal Farm false 3 2 O Alquimista true 4 2 Brida true Who supports EVERY() Well, the SQL standard has it: 10.9 <aggregate function><aggregate function> ::= COUNT <left paren> <asterisk> <right paren> [ <filter clause> ] | <general set function> [ <filter clause> ] | <binary set function> [ <filter clause> ] | <ordered set function> [ <filter clause> ] | <array aggregate function> [ <filter clause> ]<general set function> ::= <set function type> <left paren> [ <set quantifier> ] <value expression> <right paren><set function type> ::= <computational operation><computational operation> ::= AVG | MAX | MIN | SUM | EVERY <-- yes, here! EVERY! | ANY | SOME | COUNT | STDDEV_POP | STDDEV_SAMP | VAR_SAMP | VAR_POP | COLLECT | FUSION | INTERSECTIONAnd, of course PostgreSQL! But if your database is not PostgreSQL, don’t worry. EVERY() can be emulated on EVERY() database using SUM() and CASE expressions. Here’s how to emulate the first query: -- SELECT EVERY(id < 10) -- FROM bookSELECT CASE SUM(CASE WHEN id < 10 THEN 0 ELSE 1 END) WHEN 0 THEN 1 ELSE 0 END FROM book; Or as window functions -- SELECT -- book.*, -- EVERY(title LIKE '%a') OVER (PARTITION BY author_id) -- FROM bookSELECT book.*, CASE SUM(CASE WHEN title LIKE '%a' THEN 0 ELSE 1 END) OVER(PARTITION BY author_id) WHEN 0 THEN 1 ELSE 0 END FROM book; And, as always on this blog, we’re happy to conclude that the upcoming jOOQ 3.6 will now handle EVERY(emulation) for you, so you can write: DSL.using(configuration) .select(BOOK.fields()) .select(every("%a")) .over(partitionBy(BOOK.AUTHOR_ID))) .from(BOOK) .fetch(); Have fun with this new function!Reference: A True SQL Gem You Didn’t Know Yet: The EVERY() Aggregate Function from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog....

Java EE Workflows on OpenShift (Tech Tip #64)

                       This webinar shows how create a Java EE workflow on OpenShift using WildFly, JBoss Tools, Forge, Arquillian, and OpenShift. Specifically it talks about:How a Java EE application can be easily developed using JBoss Developer Studio and deployed directly to OpenShift Set up Test and Production instances on OpenShift Enable Jenkins to provide Continuous Integration Run the tests on Test and push the WAR to ProductionMore detailed blog entries are at:Deployment Pipeline for Java EE 7 with WildFly, Arquillian, Jenkins, and OpenShift (Tech Tip #56) Arquillian tests on a WildFly instance hosted on OpenShift (Tech Tip #55) Java EE 7 Hands-on Lab on WildFly and OpenShift (Tech Tip #33) Getting Started with WildFly in OpenShift and JBoss Developer Studio (Tech Tip #21)And a lot more at Enjoy!Reference: Java EE Workflows on OpenShift (Tech Tip #64) from our JCG partner Arun Gupta at the Miles to go 2.0 … blog....

JavaFX in the browser

Lately Carl Dea and I have started a new project to bring JavaFX 8 into the browser. Today I want to introduce the first two proof-of-concepts that we created to see if this idea is feasible at all. For the impatient, here are the links to the PoCs. But be warned, startup time is horrible at this point. It can easily take 1-2 minutes until the JavaFX application starts. proof-of-concepts show a number of rectangles and circles in different colors. Implementing these shapes gave us a rough understanding of the underlying technology and we gained a first impression of the expected complexity and effort. The proof-of-concepts also include a circle moving back and forth. While this animation is anything but spectacular, it gives us an upper bound of the expected performance. If we are not able to show this simple animation with acceptable performance, we do not need to waste time on more complex animations. The proof-of-concepts use Doppio at the core, which is just an astonishing project. Doppio is a JVM implemented in JavaScript running in the browser. Which once again proves the coders version of Rule 34: “If you can think of it, there is an implementation in JavaScript…” To be honest, I was very skeptical of this approach. How good can the performance of such a JVM be? On the other hand, JavaScript became amazingly fast in recent years and as Hendrik Ebbers jokingly pointed out recently, these days nothing gets more aggressively optimized than JavaScript. It was worth a try. As you can see in the PoCs (which hopefully started by now), especially in the second one, runtime performance is surprisingly good. Consider once again what you are looking at: This is a standard JavaFX application compiled into byte code, which is interpreted (AFAIK Doppio does not do JIT so far) in a JVM implemented in JavaScript. And the JavaFX runtime that is used is almost identical to the standard implementation. Doppio supports Java 6 only, but the JavaFX runtime is based on Java 8. The Doppio team is working hard to support Java 8, but as of now we have to bridge the gap somehow. We decided to use RetroLambda, mainly because the JavaFX port for Android already uses it. It is an extremely useful tool, which takes Java 8-compliant byte code and migrates it to Java 7 or even Java 6 byte code. So far it worked flawless for us, only default methods are not supported yet. I am not sure, if it is production ready, but if you were stuck with Java 6 or Java 7, would like to use Java 8 features, and you have extensive testing in place, it is worth checking out. The proof-of-concepts use different approaches to render the JavaFX Scene on the screen. The first PoC uses the software renderer. It is part of the JavaFX runtime and, as the name suggests, almost everything to render a scene is done in Java. The result is an array of bytes, which we must copy to the screen. The custom renderer on the other hand tries to use as much of the HTML canvas API as possible, i.e. to render a circle, the custom renderer uses the method arc(). Usually the second approach is much faster, because it can take advantage of optimizations that are part of the platform. But it also means that the implementation will be limited by the possibilities of the platform. For example advanced features with video (e.g. rotation and overlays) and a number of effects are often not supported. The next steps are at least two more prototypes and then we will decide which route to follow. And we need to fix the startup time. Stay tuned!Reference: JavaFX in the browser from our JCG partner Michael Heinrichs at the Mike’s Blog blog....

Implementing the ‘Git flow’

Git can be used in a variety of ways which is cool. But still, when working within a team, it is good to have a consensus on a common, shared approach in order to avoid conflicts. This article quickly explains how we implemented the “git flow” pattern in one of our projects. Git-flow… …is a popular strategy which works around the master branch, but in a less “aggressive” way (than the GitHub flow pattern for instance). You have two main branches:  master branch contains the latest production code that has been deployed, and versioned with appropriate tags for each release. develop branch that gets branched off master and contains the latest code for the next feature that is being developed. For each new feature there might be lots of feature branches (always branched off the “develop” branch). Beside the main branches, there are so-called supporting branches:Beside those, there are supporting branches:feature branches contain the development state for a single feature of the overall product (i.e. a user story). They are merged off the develop branch. hotfix branches are branches for quick and severe bugfixes. they are usually branched off the master branch, fixed in the hotfix branch and then merged back in master and develop as well. release branch is a branch for preparing the next release. No new features will be developed on this branch but rather it contains some last fixes (also bugfixes) and adjustments for going into production.Many people prefer to see master as their development branch and instead have a dedicated one for the production environment. Such a production oriented branching strategy hasmaster branch which contains the actual development code (corresponds to the “develop” branch in the git-flow model) production branch contains the deployed code.Supporting branches are:feature branches which contain the development of specific features and are branched off master and merged back into master hotfix branches (works like in the standard git-flow model) release branch (works like in the standard git-flow model)Usage In my opinion tools are great as they (mostly) give you some productivity boost. Nevetheless you should always understand what they do behind the scenes. This section lists the commands you’ll need to manually implement the production-oriented “git flow” pattern shown above. First of all you have to initialize an empty repository and eventually connect it immediately to your remote one. Obviously, feel free to skip this step if you already have one. $ git init $ git remote add origin git@..... Furthermore I’d suggest to also add a .gitignore file. You may start from an existing one based on your project type: Github .gitignore repository. “push” everything up to your remote repo. $ git push --set-upstream origin master Create a new Feature From master $ git pull $ git checkout -b userstory/login Do some commits and then publish the feature on the remote repo (if not a tiny one of a couple of hours) $ git push origin userstory/login Update feature from master Frequently update from origin/master to get the latest changes that have been pushed to the repo by your peers. $ git fetch origin master $ git rebase origin/master Alternatively checkout your master branch and execute $ git pull master $ git checkout <yourfeaturebranch> $ git rebase master Note, when you rebase with master, your branch might not be easily updateable with its remote counterpart (given you synched it up to a central repo). In such case you can use the --force flag. Caution! Inform yourself on the Git docs about the potential dangerous side effects when using the --force flag! Only use the force flag if you haven’t shared the branch with anyone and it is simply your central backup. Force overwrites the history with your local repository state inside your current branch. $ git push --force origin <yourfeaturebranch> Finish a feature Merge it back into master $ git checkout master $ git pull $ git merge --no-ff userstory/login --no-ff means no fast-forward to keep track from where certain changes have originated. In order to not forget the --no-ff flag you might want to configure it as the default behavior when merging into master by executing the following command: git config branch.master.mergeoptions "--no-ff" In case of conflicts, resolve them and then push the master $ git push and remove the userstory (locally and remote) $ git branch -d userstory/login $ git push origin :userstory/login Prepare release $ git checkout -b release/0.1.0 Publish production $ git checkout production $ git pull $ git merge --no-ff release/0.1.0 $ git tag v0.1.0 $ git push --tags origin production Delete the release/x.x.x branch. Create a hotfix $ git checkout production $ git checkout -b hotfix/login-does-not-work After testing it, merge back into production $ git checkout production $ git merge --no-ff hotfix/login-does-not-work $ git tag v0.1.1 $ git push --tags Obviously also merge those changes back to master as well $ git checkout master $ git merge --no-ff hotfix/login-does-not-work And then delete the hotfix branch $ git branch -d hotfix/login-does-not-work Ok..I’m a Jedi..give me some tools Git flow CLI tool Git Flow is a git command line extension to facilitate the usage of the “git flow” pattern.Download & install Git flow cheatsheetSo, if you mastered to use the git flow pattern manually, you’re ready to go with it. Haacked’s Git Aliases Phil Haack (former Microsoft employee and now working on GitHub for Windows @ GitHub) published an interesting set of 13 git aliases to boost your productivity. You might want to take a look at them: To install them, simply copy&paste the aliases into your .gitconfig file. You should find it in your user profile directory (~ on unix systems; C:\users\<yourname>\ on Windows). Configuring Jenkins Please refer to my recent blog post “Git flow with Jenkins and GitLab” for further details on how to configure your build environment. How we use it – our pipeline We adopted the git flow pattern in one of our projects with a team getting in touch with git for the first time (they used TFS before). I introduced them to the Git basics and then they started straight ahead and surprisingly the switch was really easy. By using git flow we minimized the conflicting merges and thus potential problems in the development flow. So how did we use it? The team applied some kind of Scrum (we’re new to it, thus “some kind of”). We have two weeks iterations with an initial planning phase (usually on thursday morning) and we have the tester on the team (yay!).At the start of the sprint cycle, our devs take their user stories (on Trello) and create corresponding feature branches having the pattern userstory/<trello-card-#>-userstory-title for userstories, task/<trello-card-#>-title for tasks and bug/<trello-card-#>-title for bugs. The develop on the feature branches and fequently update them with master (see git flow usage above). If the story/task/bug’s implementation takes longer than a day or two, the branch gets pushed to the remote GitLab server (for backup reasons). Each of these pushes gets automatically build and tested by our Jenkins. Once finished with the implementation, the developer either merges it with master or creates a merge request on GitLab assigned to another developer for code reviewing. When master gets pushed to GitLab, Jenkins automatically takes it and publishes it to our dev server instance. Once every night, the master branch gets automatically published to our test server instance s.t. the tester in our team can continue to test the implemented stories and either mark them as done or reject them within our spring cycle. Furthermore a series of automated jMeter tests get executed that verify the correct functioning of our REST api as well as the performance of our endpoints. After the 2-weeks-cycle one of our devs prepares a release (see the kind of commands to execute in the “git flow usage” above) by merging master onto production. This is automatically detected by Jenkins which – again – publishes to our preproduction server instance which is also accessible by our customer.We do not use release branches as we don’t need them so far. There is no preparatory work to be done, although that might eventually change in the future. That’s the flow we came up with after a few iterations and dicussions within the team and with our tester. What’s your approach?? I’d be interested to hear in the comments. This article has been re-published on the following partner sites: Implementing the ‘Git flow’ from our JCG partner Juri Strumpflohner at the Juri Strumpflohner’s TechBlog blog....

Patching Weld 3 in WildFly 8.2 – First Experimental RI of Java EE 8

Java EE 8 is moving along and several new component JSRs have been filed. JSR 365 will define the specification for CDI 2.0. Red Hat has already started working on the implementation prototype in Weld 3 and Alpha3 was released recently. The Java EE 8 compliant application server from Red Hat will be WildFly where all the different technologies will be implemented. In the meanwhile, how do you try out these early experimental releases? Tech Tip #29 showed how to patch WildFly 8.x from a previous release. This tip will leverage that mechanism to install Weld 3 Alpha3 in WildFly 8.2. You can also download Weld 3 Alpha3 Standalone or Weld 3 Alpha3 as patch to WildFly 9.0 Alpha1. The instructions are rather simple:Download and unzip WildFly 8.2: wildfly-8.2.0.Final.zipDownload Weld 3 Alpha3 Patch for WildFly 8.2:curl -L -o the patch as (also available in README bundled in the patch):./wildfly-8.2.0.Final/bin/ --command="patch apply ./" { "outcome" : "success", "result" : {} }Start WildFly:./wildfly-8.2.0.Final/bin/standalone.shRun a simple CDI test from javaee7-samples:mvn -f cdi/nobeans-xml/pom.xml test -Dwildfly-remote-arquillianand see output in the WildFly console as:20:53:30,434 INFO [] (management-handler-thread - 1) JBAS014900: Content added at location /Users/arungupta/tools/weld3/wildfly-8.2.0.Final/standalone/data/content/4c/c6675b4f1fb33fe40dda3f94ac4979b3e2a4d0/content 20:53:30,453 INFO [] (MSC service thread 1-4) JBAS015876: Starting deployment of "test.war" (runtime-name: "test.war") 20:53:30,878 INFO [org.jboss.weld.deployer] (MSC service thread 1-5) JBAS016002: Processing weld deployment test.war 20:53:30,953 INFO [org.hibernate.validator.internal.util.Version] (MSC service thread 1-5) HV000001: Hibernate Validator 5.1.3.Final 20:53:31,131 INFO [org.jboss.weld.deployer] (MSC service thread 1-5) JBAS016005: Starting Services for CDI deployment: test.war 20:53:31,163 INFO [org.jboss.weld.Version] (MSC service thread 1-5) WELD-000900: 3.0.0 (Alpha3) 20:53:31,195 INFO [org.jboss.weld.deployer] (MSC service thread 1-9) JBAS016008: Starting weld service for deployment test.war 20:53:32,141 INFO [org.wildfly.extension.undertow] (MSC service thread 1-15) JBAS017534: Registered web context: /test 20:53:32,178 INFO [] (management-handler-thread - 1) JBAS018559: Deployed "test.war" (runtime-name : "test.war") 20:53:33,454 INFO [org.wildfly.extension.undertow] (MSC service thread 1-6) JBAS017535: Unregistered web context: /test 20:53:33,464 INFO [org.jboss.weld.deployer] (MSC service thread 1-16) JBAS016009: Stopping weld service for deployment test.war 20:53:33,490 INFO [] (MSC service thread 1-12) JBAS015877: Stopped deployment test.war (runtime-name: test.war) in 40ms 20:53:33,497 INFO [] (management-handler-thread - 1) JBAS014901: Content removed from location /Users/arungupta/tools/weld3/wildfly-8.2.0.Final/standalone/data/content/4c/c6675b4f1fb33fe40dda3f94ac4979b3e2a4d0/content 20:53:33,498 INFO [] (management-handler-thread - 1) JBAS018558: Undeployed "test.war" (runtime-name: "test.war")Note that the Weld version of “3.0.0 (Alpha 3)” is shown appropriately in the logs.In terms of features, here is what is available so far:Declarative ordering of observer methods using @Priority Ability for an extension to veto and modify an observer method Support for Java 8 repeatable annotations as qualifiers and interceptor bindings Enhanced AnnotatedType API Asynchronous events Simplified configuration of Weld-specific properties Guava is no longer used internallyMore details, including code samples, are explained in Weld 3.0.0 Alpha1 Released and An update on Weld 3. All the prototyped API is in org.jboss.weld.experimental package indicating the early nature. Here are some resources for you to look at:JavadocsMaven coordinatesorg.jboss.weld weld-api 3.0.Alpha3Feedback at Weld forums or the cdi-dev mailing list.Created Java EE 8 Samples repository and will start adding some CDI 2.0 samples there, stay tuned. Enjoy!Reference: Patching Weld 3 in WildFly 8.2 – First Experimental RI of Java EE 8 from our JCG partner Arun Gupta at the Miles to go 2.0 … blog....

Grails domain classes and special presentation requirements

In Grails we often use our domain objects directly as backing model for presentation purposes and only for specialized situations we create value holder objects or DTOs. Beginning Grails developers know how to display individual entity properties pretty easy in a GSP, such as the name of a fictional domain class…             <g:each in=”${breedingGoals}” var=”breedingGoal”> ${} </g:each> or <g:select from="${breedingGoals}" optionKey="code" optionValue="name" />but sometimes struggle when new presentational requirements come in and slightly more or combined information needs to be displayed. Special constructions are contrived, such as the following: def list() { def breedingGoals = BreedingGoal.list() breedingGoals.each { = + " ("+ it.code + ")" } render view: “viewName”, model: [breedingGoals: breedingGoals] } to not only display the name any more, but also something else – e.g. its code. And that’s when things get hairy!This looks like a sensible way to get the new correct output in the browser. But it is not. In this case entities are actually updated and leave the database in a very messed up state after a few iterations. This is the point where seasoned developers tell beginning developers not to continue down that road. If you are one of the latter, read some of GORM’s persistence basics for some background first, and get back here for some guidelines you could use, in order of my personal preference. My main rule of thumb is: Do NOT replace data by a (re)presentational version of itself. It’s not a fully comprehensive list, just to get you thinking about a few options taking our aforementioned BreedingGoal use case as an example. If the information is contained within the object itself and you have the object, just format it right on the spot. <g:each in=”${breedingGoals}” var=”breedingGoal”> ${} (${breedingGoal.code}) </g:each> A GSP is especially useful for presentation purposes. I would always try that first. Some people still get confused of the various Grails tags which seem to accept “just 1 property” of the domain class being iterated over, such as select. <g:select from="${breedingGoals}" optionKey="code" optionValue="name + (code)? Arh! Now what?" /> Luckily, sometimes the tag author thought about this! In the case of select, optionValue can apply a transformation using a closure: <g:select from="${breedingGoals}" optionKey="code" optionValue="${{ + ' (' + it.code + ')' }}" /> If this new formatted information is needed on more places to stay DRY you can put it in the object itself. In your domain class, add a getter: String getNamePresentation() { name + " ("+ code + ")" } which can be called as it were a property of the object itself. <g:each in=”${breedingGoals}” var=”breedingGoal”> ${breedingGoal.namePresentation} </g:each> If information is NOT in the object itself, but needs to be retrieved/calculated with some other logic you can use a Tag Library. class BreedingGoalTagLib {def translationServicedef formatBreedingGoal = { attrs -> out << translationService.translate(attrs.code, user.lang) } } In this example some kind of translationService is used to get the actual information you want to display. <g:each in=”${breedingGoals}” var=”breedingGoal”> <g:formatBreedingGoal code=${breedingGoal.code} /> </g:each> A TagLib is very easy to call from a GSP and has full access to collaborating services and the Grails environment. If there’s no additional calculation necessary, but just special (HTML) formatting needs Get the stuff and delegate to a template: class BreedingGoalTagLib {def displayBreedingGoal = { attrs -> out << render(template: '/layouts/breedingGoal', bean: attrs.breedingGoal) } } where the specific template could contain some HTML for special markup: <strong>${}</strong> (${it.code}) Or you need to initialize a bunch of stuff once or you’re not really aiming for GSP display you could create a (transient) property and fill it upon initialization time. Adjust the domain class, make your new “presentation” property transient – so it won’t get persisted to the database – and initialize it at some point. class BreedingGoal {String code String name String namePresentationstatic transients = ['namePresentation'] } class SomeInitializationService {// in some method... def breedingGoal = findBreedingGoal(... breedingGoal.namePresentation = translationService.translate(breedingGoal.code, user.lang)return breedingGoal} Friendly word of advice: don’t try and litter your domain classes too much with transient fields for presentation purposes. If your domain class contains 50% properties with weird codes and you need the other half with associated “presentation” fields, you might be better off with a specialized value or DTO object. Conclusion You see there a various presentation options and depending on where the information comes from and where it goes to some approaches are better suited than others. Don’t be afraid to choose one and refactor to another approach when necessary, but I’d stick to the simplest option in the GSP first and try not to mangle your core data for presentation purposes too much!Reference: Grails domain classes and special presentation requirements from our JCG partner Ted Vinke at the Ted Vinke’s Blog blog....
Java Code Geeks and all content copyright © 2010-2015, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below: