Thursday, October 5, 2017

Normalizing SDKMAN Across Development Computers

Why do we need this?

sdkman is a great tool for a single-source management of software development kits for multiple frameworks. Providing a consistent location for SDKs is a priority when projects are being shared across multiple development computers, either by just copying the folders or using repositories like Subversion and Git.

The location of SDK dependencies is kept in the project files defined by the development tools, like Eclipse and IntelliJ Idea. If the project is shared or checked in or out of a repository, the last person to check it in will commit their own personal settings. Then the next person to check it out has to change the settings to match their computer, and those are what get checked back in.

Thursday, September 28, 2017

Grails Development FAQ

Updated October 10, 2017

This is a growing list of frequently asked questions (FAQ) that I encounter teaching Groovy & Grails, with an eye toward Ellucian Banner XE Self-Service development. While many of these questions are Grails specific, a few pertain to the JetBrains IntelliJ Idea IDE that I use in class. Check back to see if the list has grown bigger:
  1. Can I open multiple projects in the same window in IntelliJ?
  2. Why doesn’t my Grails classrecompile and reload in the development server?
  3. Changes to my controller and domain classes compile and work. So, why do I get random errors in the run window, often a NullPointerException, sometimes related to scaffolding?
  4. I already have the browser open on the application page that I want, how do I stop IntelliJ from launching a new page for the application if I restart the development server?
  5. Hibernate with the H2 database writes an awful lot of log messages to the Grails console!
  6. If I use respond in the controller, where is the model data in the view?
  7. Where is the model data? I can’t find it when I dump out the request in the GSP!
  8. If I create a new domain instance from the params map, the id property is not set! And, the same thing happens if I try to copy the properties from one domain object to another. What is happening?
  9. Do I need to convert a string id from the params map to an integer before using get?
  10. How do I fix the Grails SDK? It changes every time someone checks in the project!
  11. I change the Grails SDK, and now IntelliJ Idea says that Groovy is not configured!
  12. null id in ... entry (don't flush the Session after an exception occurs)
  13. Why does saving a new domain object flush database changes?
  14. On a Mac I can't see ~/.sdkman to get to the Groovy or Grails SDKs?

Tuesday, September 5, 2017

Banner 9/Grails 2.5 Development Problems and Resolutions

Updated 10/5/2017

This is a page of random problems and solutions encountered using Grails 2.5 for Ellucian Banner XE (9) Self-Service development. As new problems are resolved, they will be added to this list ordered by the resolution date.


20171005 module not found: org.codehaus.groovy#groovy-all;2.4.4

This is a grails 2.5.5 issue. Make sure that you are using Grails 2.5.0 for Banner development. Grails 2.5.5 was a bad release where projects are configured to use Groovy 2.4.4, but it shipped with Groovy 2.4.5.


20150910 JavaLaunchHelper has Multiple Definitions

This one shows up in Apple MacOS, but not in Windows. In Java 8 the class JavaLaunchHelper is implemented in both the JDK java command and in the libinstrument.dylib library. Since they both seem to be exactly the same, the message is just an annoyance that cannot be squelched.

20170902 Grails Throws a NullPointerException on Recompile & Reload

After a file is changed, such as a controller, Grails notices the change, recompiles, and reloads the file but throws an error similar to this: ERROR plugins.AbstractGrailsPluginManager  - Plugin [controllers:2.5.0] could not reload changes to file.

Update 2017-10-09: this problem has appeared for me on Linux as well. This problem has only appeared for me on Microsoft Windows systems: when a class is recompiled and reloaded, a NullPointerException is thrown, often by the AbstractGrailsPluginManager. The class is actually recompiled and reloaded, so it was not clear exactly what the problem was. Sometimes the error originates in the scaffolding system, even when the application does use scaffolding. There are plenty of comments around the Internet about disabling forked execution, but only one comment clarified why.

Banner, Eclipse, and Grails!

You can use Eclipse as a single IDE for developing both Banner Admin Pages and Self-Service extensions! It is also possible to use other IDEs for developing Self-Service extensions; NetBeans has excellent Groovy and Grails support. The focus in this post is on using Eclipse for both development environments.

Disclaimer and warning: this post may become outdated at any time, but currently the most up-to-date information from Ellucian is:
  • Eclipse 4.6 (Neon) is the most current Eclipse IDE supported for developing Admin Pages. You must use an Eclipse-based IDE for developing Admin Pages, because the required plugins for development are only available for Eclipse. The plugins have been tested with Eclipse 4.4 (Mars), 4.5 (Luna), and (4.6) Neon.
  • IntelliJ Idea Ultimate is the recommended IDE for developing Self-Service extensions. The current IntelliJ version 2017.2.3 still supports the Groovy and Grails versions being shipped with Banner.
  • Other IDEs with Groovy and Grails support may be used for Self-Service development. Support for extending Banner and using Grails will be provided, but do not count on any support for using the IDE with Groovy and Grails.
  • Banner 9 ships with Grails 2.5, which depends on and includes Groovy 2.4.

Thursday, August 3, 2017

ORM and JSON in JavaScript and TypeScript

Mapping JSON to entity objects and objects to JSON is trivial, if the objects only contain data and allow direct access to the properties. There is a bit more work if the class needs to have helper methods for things like validation, and if we want to wrap the data members with getters and setters.

The goal is to meet these requirements during coding:
  • Entity classes may include validation
  • Data members have accessor (getters and setters)
  • Entity classes may have other methods
  • Entity class type is important (this encapsulates the previous three points)
  • Missing data in the JSON source should be logged.
  • Extra data in the JSON source should be logged.
  • Support DRY - Don't Repeat Yourself
Full disclosure here: I know that there are two big problems with what I am about to describe. If you have been trying to handle ORM conversion already, you may have hit them. The problems are not insurmountable, but we'll get to that later.

Friday, May 26, 2017

Anonymous Functions and Arrow Functions are Closures

Functions in JavaScript and TypeScript are "first-class citizens;" which means that they can be passed as a parameter, assigned to a variable (and passed as a parameter), and may be dynamically created at runtime. The last stipulation is important: not only do many people consider it a major requirement to be a "first-class citizen," but creating new functions at runtime is how JavaScript and TypeScript function is built.

Dynamically creating functions at runtime is good and bad. It is good because it simplifies the code and can make it cleaner, but it is bad because there is a penalty to pay for creating all these functions.

Saturday, May 20, 2017

Safeguarding Development Environments

When I am teaching I often refer to a mistake I made years ago, typing "rm * .o" in a Unix shell while in a project folder. I realized when the shell said ".o not found" that by placing the asterisk accidentally all by itself I had selected and removed all the source for the project!

I am sure that it was not the first mistake that I ever made that corrupted a project, nor will it be the last. You or I do not even have to make a mistake; it could just be that your hardware fails or that today some black-hat exploits a security flaw that nobody has patched yet and voilĂ , all of your files are encrypted and forever beyond your reach.

In fact, it is the WannaCry ransomware attack that prompted this post! Not that it bit me, but something like it could some day...