Friday, September 23, 2011

See you at CodeRage

I have never seen so many Delphi Events as we are seeing right now.

There is definitely a buzz regarding the new Delphi XE2

DelphiLive in San Jose has completed and it was a great event.

Half the Delphi World Tour dates have past, with a several more to go.
In Utah the Delphi World Tour represented one of the largest  Delphi Event in Years.

Next Up is CodeRage  Oct 17-21, 2011.    It a FREE, virtual conference.     For those who are confused about the idea of a virtual conference.... think of of it as 50 back to back webinars in 5 Days.  

My team goes to training room with loads of junk food.    Where we discuss the sessions as they occur.      It really for good team building.

I will be sharing 4 sessions at CodeRage this year.
  • Learning Magic Tricks: The Beginners Guide to RTTI 
    • Learn what RTTI is and how to use it. This session is designed for those that have heard of RTTI, but don't know where to start.
  • Practical Magic: Why would I use Delphi RTTI? 
    • Attendees are shown several practical examples of how the RTTI in Delphi works.
  • Magic Unleashed: A Deep Dive into the Delphi RTTI 
    • In this session, we pull back the covers and explore the internals of how RTTI.pas and TypInfo.pas work inside of Delphi exposing all of the RTTI options you have to use in your applications.
  • Exploring the Delphi Debugger 
    • This session explores how to use the Delphi Debugger to find those difficult to find problems. We explore the little known features of the debugger that can make your life easier when real problems arise.
All of the RTTI sessions are back to back, allowing for Q/A after each.    With three sessions I will be able to provide more information than I have ever been able to do before.

Tuesday, September 6, 2011

XE2 and Registration Headaches.

Today I hit the registration limit on XE2.

I installed it on the following machines.
  1. Laptop (Primary for DelphiLive Presentation)
  2. Laptop (Backup for DelphiLive Presentation)
  3. Desktop (Home)
  4. MacMini, Windows VM
  5. Desktop  (Work)
Registered in in that order.   I ran in to the registration Limit with #5.    I am the only person who uses these machines.

So I think no big deal, I will request a registration limit increase.    I requested the increase and walked away from my machine for meeting.     Thinking I can wait 14 days to register no big deal.

Then I did the following.

1. File|New VCL Application
2. Ctrl-F9

Then the following dialog appears.

I have never been a fan of activation, but I have not been against it... Until Now!
Now that I can see that the 14 day grace does not just cripple the application on start-up, it annoys the developer and reduces their productivity.

The good news is that support did respond and the activation limit has been increased.     But this is just a headache that paying customers should not have to deal with.    


Thursday, August 25, 2011

New Mac and Rad Studio XE2

Note: I was given permission to blog about the Rad Studio XE2 Beta.

Today my first Mac OSX computer arrived at my home.   I have only used a Mac when working
on Sound and Lights at local theatre.   I have spent about 10 hours total time working on a Mac in the last 10 years. So I would guess this as close to a new user experience as one my expect.

The primary reason I bought the Mac is because Rad Studio XE2 supports writing applications for this platform.    I like to make sure I stay on top of the various Delphi technologies so I had to buy one.

I opened the box and hooked up the various cables.    Turned it on and I saw a little diagram asking me to turn on my touch pad or mouse.   Well I turned on the touch pad and nothing happened.   After trying various combinations I gave up and called support.   After having to power of the Mac twice we were able to get the wireless keyboard and mouse to work.      Things were not going well, and I was a bit worried I had made a mistake but things turned around.

I had installed the latest Rad Studio XE2 Beta version on my home computer, which is a Windows 7 machine.  
Then I performed the following steps:
1. File|New Firemonkey HD Application.
2. I then right Clicked on Target platform and added OSx

I knew I had to install something on the Mac but I did not know where it was or how to do it.
I opened the Help file and found it had a Huge amount of information that pointed me in the right direction.
From the little I did read I was very very pleased with the depth of coverage.

3. I Installed the Platform Assistant on the Mac according to the instructions.
4. I launched the platform assistant clicking on the "paserver.command" in
"Developer" section of finder.

5. Then in back in Delphi, I right clicked on the "OS X" Target Platform and selected "Assign Remote Profile"
6. On the "Select Remote Profile for 'OS X' Platform" dialog I pressed "Add..."
7. I walked through the Wizard and Added Information about my Mac.

8.  Then finally I selected the new profile that was created.
9.  I then pressed the run button.

The application appeared on the Mac as expected.

I must say the out of the box experience with Delphi and the Mac looks very polished, it was very easy to setup.  I spent more time trying to get the wireless mouse and keyboard to work than getting Rad Studio configured and my first App running.

Now that I have a basic app running it's time to really explore how FireMonkey integrates will both Windows and OS X.

For more information check out the Rad Studio XE World Tour or the Delphi Live conference.

Wednesday, June 15, 2011

THtmlWriter - First Look

I wanted my build process to automatically generate a web page with what was changed in the given build.   Basically I had to query our Internal Bug Tracking system and produce a web page. Allowing me to take a
snapshot of bug tracking system as it looked liked when the build was produced.

This was going to be a simple console application that our build could run.  

So I decided to try THtmlWriter written by Nick Hodges.

I spent more time reviewing the code of THtmlWriter than I did actually using it.

It was very easy to use, and will most likely use it in future

If you need to produce HTML from Delphi application it's worth looking at this.

So here is my +1 Vote for THtmlWriter

Tuesday, June 7, 2011

Application -vs- Component Developer

During Interviews I have  heard the following from candidates.
"I am Application developer, I use components, I don't build them."

I typically have thought well I have found another "point and click" developer who is not familiar with OOP.   Since I have been at my component no candidate who has said this has been hired.

Recently I ran into an exception (outside of an Interview) a Delphi Developer who was very familiar with OOP but had still not built a component. I realized that there an artificial barrier into component development, that many might see.    In a future blog postI will confront this artificial barrier head on and show how easy it is to do component development.  This post is show some of the arguments of why we would want to do component development as an application developer.

In 2007 we converted our application from BDE to DBX. We had written an application that converted all TQuery components to TDbxQuery components.  

The process of conversion to the 3 component model of DBX (TSqlQuery -> TProvider -> TClientDataset) was going to be error prone.   It was also going to take an insane amount of time that we were not willing to spend.

So we spent a few days creating a component that looked like and behaved like TQuery but internally used the 3 Component DBX model.  It was similar to TSimpleDateset but had properties and functions that matched existing  TQuery functionality that we used.  This allowed for a search and replace of instances of TQuery with TdbxQuery.   This allowed us to complete this conversion in less time that if we had just used the built in components.     Since we maintained the component we were able to expose any functionality of the 3 components model that we needed.

During this process we realized we had hundreds of  TDBGrid components.     So we decided to help our application for the long term.   We replaced TDBGrid with TDwsGrid.    Initially the code looked something like this.    It basically offered nothing over TDbGrid.

TDwsGrid = class(TCustomDBGrid)
    property Align;
    property Anchors;
    property BiDiMode;
    property BorderStyle;
    property Color;
    property Columns stored False; 
    property Constraints;
    property Ctl3D;
    property DataSource;
    property DefaultDrawing;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property FixedColor;
    property Font;
    property ImeMode;
    property ImeName;
    property Options;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property TitleFont;
    property Visible;
    property OnCellClick;
    property OnColEnter;
    property OnColExit;
    property OnColumnMoved;
    property OnDrawColumnCell;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEditButtonClick;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnMouseWheel;
    property OnMouseWheelDown;
    property OnMouseWheelUp;
    property OnStartDock;
    property OnStartDrag;
    property OnTitleClick;

The other day I had a look at this component, it now does the following.
  • Sorts the Grid based on Click of column Title
  • Persists Column positions and sizing to a configuration file.
  • Ability to Export to Excel.
It's not a huge amount functionality but it allowed us to add this to many screens without how having to place this code to do this in every place we used TDbGrid.      

When explaining this to application only developer one might expect a response of.  "Well why not buy a 3rd party control that does that?"   My answer  "We did just that, when we had the budget we purchased a TMS Subscription and now use TDBAdvGrid in many places."   

But the experience previously learned still applied to 3rd party component packages.   We now are in the processed of  creating, our new component which now looks like this:

TdwsAdvDbGrid = class(TAdvDBGrid)

Allowing us to add additional functionality to TAdvDBGrid if we need it.   Granted for now we don't need to add anything.   But the lesson learned from the previous experience has shown the value.

This does not just apply to additional functionality, it also applies to common custom settings.
Say for example every time you use a TEdit you need to change the Font to comply with a standard
you have set.   Instead of doing the tedious mistake ridden work of doing this.   Instead create a TMyEdit then use that instead of TEdit.  


  SysUtils, Classes, Controls, StdCtrls;

  TMyEdit = class(TEdit)
    constructor Create(AOwner : TComponent); override;

procedure Register;

{ TMyEdit }

constructor TMyEdit.Create(AOwner: TComponent);
  Font.Name := 'My Crazy Font';

So basically a developer should be able to do both, application and component development.    Taking the time to learn component development will only help you in your your abilities to create great applications.

Thursday, June 2, 2011

Runtime/Designtime what? Delphi Packages

To most Delphi developers a package is typically where you would place components so that you can drop them on your forms.

So one might assume that a 3rd Party Component developer would know how packages work.    Well over the years I have seen several of these developers make basic mistakes when it comes to Delphi packages.

The application I work on is built with runtime packages.  We currently have to deploy 208 packages.
Management of Packages and having the built correctly is paramount for us.    Not all packages involve components, but the most common mistakes happen at that level.

This blog post is my attempt to help developers understand one area of packages, that I typically see mistakes.

A package is just a collection of units that are complied together into a BPL.

Here is the package sources for brand new package with a single unit.
package Package2;             

{$R *.res}
{$ALIGN 8}
{$IMAGEBASE $400000}


  Unit13 in 'Unit13.pas';


There are two key sections requires and contains.

Contains is the list of units that your package contains.     Requires is the list of other packages your package needs  to compile.   For example say you have a  pkgBaseBall.bpl that contains a unit called baseball.pas.
Then you create a new packages called pkgSports.bpl that contains a unit called sports.pas which listed baseball.pas in it's uses clause.    You will need to add pkgBaseBall to the requires clause the package named pkgSports.bpl

Key Files involved in package development.
  • *.DPROJ - XML File in MSBUILD format that contains project options and files.
  • *.DPK - Main source code of the package.   (It's the code listed above)
  • *.BPL - Compiled Binary 
  • *.DCP - Delphi Compiled Package, contains information about he interface section of the contained units. 

Package Types
There are 3 basic types of  Packages.

  • Designtime only
  • Runtime only
  • Designtime and runtime 

Runtime Packages

When creating a Delphi you have the option to build with runtime packages.   This option is found in the project options.

If you build with packages you must distribute the packages (.BPL files) your application uses.

Most Delphi application that I have seen are build without runtime packages.    Typically these developers tend to not realize the impact bad package design can cause on application that uses runtime packages.

When building with runtime packages the list of package you must distribute is semi-colon delimited list next to the check box for Build with run time packages in the project options.     The only files you need to distribute for applications build with runtime packages is the BPLs.    The other key package files do not need to be distributed.

Runtime packages should never contain or require designtime code.

Designtime Packages

Designtime packages are where you place your design time code.   This includes 
  • Property Editors
  • Component Editors
  • Open Tool Experts
  • References to other packages that are design time.
  • Component Registration "i.e. the Register method."
Designtime packages should never contain runtime code.

Designtime and Runtime

This is the lazy developer package.   I don't want to create and maintain two packages, so I will just use one. This seems easy at first, but if not done carefully it leads to the most common mistake I run into.    Then write some code  that requires a designtime only package.    This in effect makes your package designtime only regardless of your package type selection.      It's easy to do any property or component editor will require DesignIDE which is design time package that you can't distribute.

The Rules 
The summary version of common mistakes.

  1. "Runtime" Packages should never contain Design time Code
  2. "Designtime" Packages should never contain Runtime Code.
  3. "Designtime and Runtime" Packages should never Require "Designtime"  Packages.  
  4. "Runtime" Packages should never Require "Designtime"  Packages.  
  5. Avoid "Runtime" Packages that  require "Designtime and Runtime" Packages
  6. Avoid the use of "Designtime and Runtime" Packages.

Why do I care?

If an application builds with runtime packages, and someone screws this up you will find that application requiring deployment of design time packages to work. If you do deploy the runtime package, you may run into a a runtime error "Application is not licensed to use this feature"  This is because your using files that you should not be distributing.

Tuesday, May 31, 2011

Find Text in Delphi - Evolution of a Feature

Every application goes through evolution, where a feature is completely rewritten to be better.

Understanding how a given Feature is used is important before undertaking the rewrite, to know how your going to impact your user base.  

The case I am going to point out today is the difference between the Delphi 2007 and XE find text mechanism.    The XE version changes are frustrating at best.    Do see what I am talking about
do the following in both IDE's.
  • File| New VCL Application
  • File| New Form  (So you have two blank forms open)
  • Navigate to the code of one of the forms
  • Ctrl-Home (Move to top of unit)
  • Ctrl-F  (Delphi 2007 Dialog - Delphi XE it's at the bottom)
  • Enter "Form" as the search word 
  • Press Enter (First Match is found in uses)
  • Press F3 (Second Match Found)
  • Press Ctrl-Home (Go back to top of document)
  • Steps change from here on out....
  • Delphi 2007
    • Press F3 (Finds First Match Again)
    • Change to second unit's source code
    • Ctrl-Home
    • Press F3 (Finds First Match in 2nd Unit)
  • Delphi XE
    • Press F3 (Nothing happens, Argh the search window says "Form" nothing is found. QC: 80696)
    • Ctrl-F  ( Text changes to "Unit" QC: 92388)
    • Retype : "Form" 
    • Press Enter
    • Change to second unit's source code
    • Ctrl-Home
    • Press F3 (Nothing happens , Argh.   Note: The search window at bottom is not visible)
    • Ctrl-F ( Text shows "Unit" )
    • Retype : "Form" 
    • Press Enter (Finds First Match in 2nd Unit)
Update:  If I restart Delphi and the Press F3 and nothing happens step works.    Something is causing it to break just don't know what it is.

It's also bad if you search on a term don't find it and want to use the Find in Files functionality.   But, I think  I made my point with the steps above.

I have heard the arguments about the new find method being better.    Personally I could care less if it's a dialog or at the bottom of the form.    The new method is even entered it as bug in QC: 80695

What I do care about, is that the functionality works for me and not against me.    

So as evolution occurs in your application, take a moment to realize the use case scenario of the existing functionality.   That way you impact your users for the better and not for the worse.

Saturday, May 14, 2011

The Joel Test The Evolution of a Team.

Every place I have worked has had a different staff hiring and/or contractor selection process.       When I started working with my current employer the process was simple.   Come in for one interview, after reviewing the resumes, and a brief conversation with each candidate a decision was made.

A bit later I became the one in charge of doing the hiring.     I followed the same basic model for awhile, then I was bitten.    I had a few bad apples.      I then read  Smart and Gets Things Done: Joel Spolsky's Concise Guide to Finding the Best Technical Talent, which talks about the Joel Test so I took the test from my point of view of my team.
  1. Do you use Source Control? (YES)
  2. Can you make a Build in one Step? (NO)
  3. Do you make Daily Builds? (NO)
  4. Do you have a Bug Database? (YES)
  5. Do you fix bugs before writing new Code? (NO)
  6. Do you have an up-to-date schedule? (NO)
  7. Do you have a spec? (NO)
  8. Do Programmers have quiet working conditions? (NO)
  9. Do you have the best tools money can Buy? (YES)
  10. Do you have testers? (YES)
  11. Do new candidates write code during their Interview? (NO)
  12. Do you do hallway usability testings? (NO)
So our test was a 4 out of 12.    I wish I remember how long ago I did that, but things have changed since then and even our YES answers have became better.   
  1. Do you use Source Control? (YES) 
  2. Can you make a Build in one Step? (YES) 
  3. Do you make Daily Builds? (YES) -
  4. Do you have a Bug Database? (YES)
  5. Do you fix bugs before writing new Code? (YES)  
  6. Do you have an up-to-date schedule? (YES) 
  7. Do you have a spec? (YES) 
  8. Do Programmers have quiet working conditions? (NO) 
  9. Do you have the best tools money can Buy? (YES)
  10. Do you have testers? (YES) 
  11. Do new candidates write code during their Interview? (YES) 
  12. Do you do hallway usability testings? (YES)  
New Score 11 of 12, not perfect but much better.

The quality and the output of our team has increased dramatically in the past few years.    Some of that is attributable to doing the things on that list.

Do you use Source Control?
When I started we were using Visual Source Safe, we have improved in this area by switching to Subversion.
We never used branching before, now it's common to branch.    We have built a one button deploy of our software using FinalBuilder.   When we select the option to deploy to production which automatically tags the revision number that was used to build the software.    We are currently investigating Mercurial or GIT but we have not decided on which and need to find a logical break to switch.

Can you make a Build in one Step?  Do you make Daily Builds?
We purchased FinalBuilder several years ago which helped made this a reality.    Our first build script was triggered as needed.   It was run on an old desktop machine.  We then step it up on a timer and it ran every hour, then our speed of our build decreased and we had to run it every two hours.  

Our initial design was that we built and then deployed in the same script.    That was a mistake, as we had to rebuild the application every time we change where we wanted to deploy  For example Development, Test, QA, Production.     So the scripts were changed to build and the deploy to a staging directory.   Then we could deploy to any of the 4 environments.   This insured that the exact same binary that was tested was moved into Production.  

We then invested in FinalBuilder Server which allowed us to start the build every time someone committed.
This improved our turn around time for our testing team, but the builds where still quite long.   So we took some time to analyze what was slow, fixed some problem areas of our scripts and invested in better hardware
for the build.    Our builds now take 10 minutes to complete, instead of the 2 hours.

Do you have a Bug Database?
Our first bug database when I arrived was a single table Delphi application that stored a limited single description of a problem, who it was assigned to and if it had been resolved.      Since then we adopted
an Bug Tracking database that another team had built.   It's web based and has nearly everything we
need.    We have used the TortoiseSVN bugtraq properties to Integrate our Bug database with SVN.
We also track new development in our Bug Tracking Database.   This allows to to tie development
requests regardless of type to the actual code that implemented them.

Do you fix bugs before writing new Code?  
We don't fix all of the bugs in the application before we write new code.  However, if we want to write new code in a specific area, we find the existing bugs in that area and fix them before heading off.

Do you have an up-to-date schedule?
We try to be agile in our process.   We hold daily stand-ups, and do iterations.   Our planning of what occurs in each iteration is working as expected.    As we have refined our process our ability to know how long
something is going to take has improved dramatically.   We still are not accurate, 100% of the time but things
balance out more often that not.

Do you have a spec? 
We did not have specifications for the longest time.   But last year we completed a several month project to develop business rules for all areas or software covered.    This is useful as the business desires to change an area they update the existing documentation.   It really helps to find the dependencies and test all downstream code.    It also gives direction on what is needed to the software developer.   We don't spend time with UI specification, unless it's critical.   Business rules is usually more than enough here.

Do Programmers have quiet working conditions?
This actually has become worse since I started, our cubical sizes have shrunk.   I have no control on cubical sizes, so I have focused on what I can control.    Many of the developers now where headphones to attempt to get quiet working conditions.   I personally own two pairs of Audio-Technica ATHM40FS Precision Studio Headphones, one for work and the other for home.    They use a 1/4" Jack so if your trying to use your 1/8" Jack  you will need an adapter.    It's my only way to find a quiet working environment, but they do work, I can't hear the phone ring when they are on :-)

Do you have the best tools money can Buy?
When I arrived we had Delphi 3 and Delphi 7 was was the latest version.   They quickly upgraded, so I have always felt like I had the best tools.   But since that time we have turned to Maintenance for all of favorite tools, so we have access to the latest tools.   It also make budgeting easier.  

Do you have testers?
When I first arrived we had a loose group of super users who tested as part of there responsibility.    We still have these testers, but we also now have a formal team of people dedicated to the QA of the product.   This really took some time to change, but the benefits are huge.

Do new candidates write code during their Interview?
This is what really was the genesis of this blog post.     Although team fit/personality is part of the equation it's
not nearly as important as being able to code.  If your hiring a developer on just an Interview your bound to find "Bad Apples"

Recently we hired two Contractors, we had over 20 applications and they all looked like qualified Delphi developers.   We sent out a written interview. With some SQL questions, we also had two simple coding questions.   They both could have been answered with little work in less than 8 lines of code.    I was amazed by the number or 30+ lines of code answers.

This quickly reduced the pool of candidates below 10.     We then did some actual Interviews reducing the pool of candidate even more.    Then we sent them off on a 3 hour coding assignment, with full access to the Internet.

Some people familiar with the process call it brutal, but I have yet to select someone who has poor coding skills but is great in an interview again.

Do you do hallway usability testings? 
We could do more to promote this, but it's common for a developer to pull someone at random to come look at something to see how they react.

In summary

This took quite a bit of time to implement, it was not an over night process.    But each individual step along the path has improved our team.    It's something I would encourage each development team to consider.

Monday, February 14, 2011

Happy 16th Birthday - Delphi

Happy 16th Birthday - Delphi!

Thank you again, to all those involved with Delphi.

Last month I was able to go to San Francisco to talk as a Rad Studio customer to talk to Embarcadero sales team.    Where I was able to meet most of the executive team and hear some directions and plans.   From the small little bits I learned there I can insure you that the direction of Delphi is in good hands.    Some of this has been hinted at during Jim's Podcast's with Allen Bauer, episodes 44, and 45.

Last year I posted a  Happy Birthday Delphi message.    At the end of that message I asked for Delphi to find it's self back into the entry level market.     I please with the directions that have been taken.     The Delphi Starter Edition has been released with a price point that opens the entry level market again.   I have also learned that the academic pricing is available for the product that is 90% of the list of the original product.  For a student this means that the professional edition can be purchased for around $100 USD which is the same price as the starter edition, and for labs I think it can be even cheaper.

Thursday, February 10, 2011

Windows 64Bit OS - Directory Layout

Short and sweet, as I had someone ask me about this today...

The \windows\system32\ directory on 64 bit version of  Windows does not contain 32 bit files it contains 64 bit files.    The 32 bit files are stored in \windows\SysWOW64

WOW stands for "Windows on Windows"

Go figure, the 32 bit files are in a directory with 64 in it, and the 64 bit files are in a directory with 32 in it.

According to the road map the next version of Delphi should be able to produce 64bit applications so it's important to know this detail.

Friday, January 7, 2011

Job Openings @ State of Utah

I work for the Department of Technology Services for the State of Utah.
I am assigned to work at the Department of Workforce Services.

We recently have opened up a few new State Employee based position, which is really a rare thing.

All Jobs at the State of Utah can be located here:
These are all Full-Time positions with work being performed in Salt Lake City, Utah.

Benefits are good, we work Monday-Thursday for ten hours a day, so you always have
a long weekend.   We have a good working environment.   We also have excellent Benefits
which include (not a complete list) medical, dental, and life insurance.  1.5% employer contribution into 401(k).   Annual, Sick and Holiday Leave.  Finally last but not least a Pension with 4 years to become vested.

On my team I have two openings for Delphi Developers.     We currently have 10 People on my team, we practice agile techniques development.

My team currently uses the following technologies.


  • Rad Studio XE Enterprise (under maintenance so we always have the latest version) 
    • Delphi Win32 2007, XE  (Primary Development Tool)
    • Delphi Prism XE    (Secondary Development Tool)
    • C++ Builder 2007 & XE (Limited)
  • Visual Studio C++ Express (Limited)
  • C# (Limited) typically using Sharp Develop


  • Oracle 10g (Project underway to move to 11g)
  • Sybase (Limited)

Tools (list not complete)

  • Subversion
  • Final Builder
  • Test Complete
  • Toad

Libraries (list not complete)

  • JCL 
  • Envision Imaging Library
  • TMS Components
  • Rave Reports 
  • Gnostice eDocEngine
  • Turbopower Abbrevia
  • Turbopower LockBox

Delphi Job details listed here:

On our web team we also have two openings for C# Developers details listed here:

We also have a Versta Developer opening which is a framework based on Java.

If someone wants to be considered for multiple positions they need to apply for each
as they are under different hiring managers.