Windows 7 on a Macbook Pro
I’m generally not a Windows person. I have used Windows since the product came out but mainly at a place of business. I have had Windows on early PC’s but I quickly switched to RedHat linux when they produced a linux distribution. My use of Windows has been based on OS availability and in-house policy. I have recently replaced a macbook pro and I’ve added Parallels virtual machine manager and Windows 7 Professional.
I am really impressed with Windows 7. It’s actually quite refreshing to use a distribution of Windows and have a pleasant experience. I have Microsoft Office 2007 and it’s nice to be able to move in and out of Windows on Mac OS-X Lion. And, with 8 GB of RAM, Lion seems to run without a hitch. I have had no issues so far with it.
After I installed the desktop tools for Parallels, the Windows 7 graphics looked really nice. And with Parallels you can run in full screen almost forgetting the fact that you’re typing on an Apple product. Check out the screen capture taken from Windows 7 using the Snipping Tool.
Planning Agile Tasks
When you’ve decided that you are going to use agile methods for a software development implementation, you may think in user stories. This is good for large teams but I think testable components describe more measurable and productive tasks for the very small team. My implementations are generally handled by me. I’m the team lead, scrum master, project manager, architect, and senior software developer for most of the projects that I’ve worked on. In many ways this is good but it never helps me market the agile process of doing software development. I was agile when agile wasn’t cool and no one was writing manifesto’s telling others how they were doing this for them.
I use JIRA to describe and manage my agile tasks. Many times I describe these tasks as user stories or release-able features. This is good for repeatable features such as CRUD operations, e.g. Add User, Delete User, Modify User, Add Item, Delete Item, Modify Item, etc. For complicated development and very customized requirements, I believe that testable components make more sense for your planned tasks or JIRA items (tasks). JUnit is my weapon of choice for Java unit testing and component development. I generally use some form of relational database and I always test Dao’s, Hibernate mappings, JDBCTemplates, or whatever provides me with data while I’m developing these components. The components are tested and developed at the same time. You may very well be “fixing” a test to be successful, but you are also understanding how the component works and verifying test assertions as they fail and you make corrections to the tests. When you’re done, you can be sure that your component will work with the next module that uses that component.
For your next agile project, try breaking “your” user stories e.g. into smaller testable component tasks. While the project manager or team lead may plan the project using user stories as her measurable unit of work, you can further break this work down. Plan your testable components and deliver quality Java.
Tougher Hiring Process
The other day I got a request for a few answers to some quite serious software development questions. These questions didn’t apply to Java directly but my knowledge of the answers comes from years of experience. I won’t share the company that wanted these answers but I’ll share with you why I received the request.
I’m presently working full time for RBC Bank USA but Cape Henry Technologies Inc. never sleeps. I’m on the fence about contracts, contract-to-hire, or full time work. It’s all about the money and doing what’s best for my family, my company, and my overall career. In my search for new opportunities, this company sent me a list of 6 questions on a single page and I was asked to respond to the questions.
I’ll share the questions and my responses and you’ll see that these questions were quite valid and I thought they deserved to be published for others to see. Intense questions indeed but I actually enjoyed answering them.
Here’s my response:
Can you identify computational complexity difference between binary search, linear search, binary tree search?
I’ll start with a linear search. For a linear search, the algorithm would be to traverse or travel a “linear” data structure such as an array and compare each key or value to the search criteria. This algorithm is time consuming because no strategy has been considered. This method is sometimes referred to as a “brute-force” search.
The binary search is a better way to search a linear data structure in a “divide and conquer” manner. The strategy here is to find the key or value by a left, right, or equality comparison to the search criterion and to successively reduce each set of comparison keys or values until the value is found or we conditionally prove the value does not exist. The initial set of values in the data structures must be ordered either numerically or alphabetically.
The binary tree search can begin with the notion of a data structure but a notion that’s yet to be created. Where the binary search can reduce the search of linear data structures pre-filled with data, the binary tree search can quickly create an efficient tree structure as values are not found, but inserted in the tree, in the optimum position for the next request. The same left, right, … greater than, less than … or equality operations are performed but the tree structure always maintains two pointers, one that’s less than or left of itself and one that’s right or greater than itself. The binary tree search can insert and delete quickly and the binary tree search is almost exactly opposite in operation of the binary search. The difference lies in the data structure. The binary tree is more dynamic than the linear array, but each has it’s place in solving data searching. The binary tree, however can be used for sorting as well as searching.
Do you have familiarity with data structures other than hashes? Also can you identify what use-cases they best fit in?
Yes. I’ve used trees, queues, ArrayLists, Vectors, splay trees, JavaBeans, C-structs, and many others. Flat-files can be considered data structures. They can be fixed size and some can be variable. Some queue types can be first-in-first-out (FIFO). Some are last-in-first-out (LIFO). Data structures come in many shapes and sizes.
Data structure choices would consist of the following considerations:
- Levels of abstraction
- Member data encapsulation
- Security
- Method needs, sorting, searching, matching, comparison, equality, etc.
- Uniqueness
- Performance
- Size and memory requirements
- Data lifecycle needs
- Namespace
Data structures should fit the need, i.e. the use case for current data structure need. For example, threading concerns sometime prescribe the use of a Vector where an ArrayList may serve the same function but the ArrayList methods are not synchronized. ArrayLists can cause strange behavior if used in high-demand web applications. Thread safety chose the data structure for us in this case. A Map is sufficient for fast retrieval of reference data e.g. State values and ISO-3166 keys, however a Map would not be a good choice for a set of 300,000 persisted values. In this case a balanced tree may be inherently used because the data is stored in a relational database. In an application environment this data is best left on disk and retrieved as needed.
Each use-case is different and data structure choice should not be taken lightly. A well-used anti-pattern is the “when you have a hammer, everything looks like a nail.” Be careful not to overly use any particular data structure because even the Java Standard Edition API has many data structures and the creation of new data structures is limitless.
Please explain differences between threads and processes.
A process is a logical grouping of microprocessor operations, sometimes described using short tokens called mnemonics. Processes are managed by the operating system (OS) and they are always identified by unique process ids. Processes are synchronous and do not execute on the microprocessor in parallel. Processor instructions are serial. Interrupts stop and start processes in such a small time-slice that it seems as if our computers do everything at once.
Threads are the smallest unit of work handled by the OS and they also consist of microprocessor instructions but threads are managed by the process. Threads can be logically described using Java code and these threads (again) can seemingly be run in parallel on the microprocessor(s) core(s). This is a complicated subject and compilers are evolving into implementation and build machines that mold software into efficient programs that make full use of todays sophisticated new microprocessors.
Can you demonstrate basic knowledge of SQL?
One of the most simplest queries using SQL would be to select all columns and all rows of a table. E.g. “select * from my_table”. This query uses the wildcard character “*” to select all columns from “my_table”. Because a where clause was not used, the query returns all rows. Where clauses are used to filter or restrict the number of rows returned or to return specific rows desired. An example of a single row might be “select firstname, lastname from employees where firstname = “David” and lastname = “Whitehurst”. This would return the firstname and lastname columns of the employee table and the employee “David Whitehurst” if he exists.
Sometimes you want to know how many rows are in the employee table. This can be done with “select count(*) from employees”.
A table called “employee_skills” may contain various skills for each employee. You may want to know, of the employees on file, what different skills do our employees possess? E.g. “select distinct employee_skill from employee_skills”. Overlapping skills exist in this table because the table is used to map skills to employee, however the “distinct” keyword filters the duplicates and only returns the unique rows.
SQL is used to join tables on keys to return data from one table or the other or both.
SQL can also be used to call stored procedures in databases that support them. Also most every relational database has formatting and data-manipulation functions built in that extend the ANSI SQL-92 set of keywords and tokens.
Enterprise databases such as Oracle also allow the use of comments with SQL statements so that the developer or database analyst can override the database’s query optimizer and tune queries for best performance. I have seen queries on 8 million row tables take minutes and after tuning run in less than 15 milliseconds.
Can you describe operating system facilities that help with distributed computing?
I am not well versed on multi-core processors but new languages such as Scala were designed for high-performance scalable applications. I think that cores allow for true parallel processing within the processor itself. The trick would be how developers write code that utilizes the cores collectively.
New technologies like Cloud computing can take advantage of processes and threading to manage huge tasks by breaking them down into tiny sub-tasks that run on many computers and are managed by highly fault-tolerant applications. These applications would assume “failure” always exists.
A good example of a fault-tolerant distributed work system is Apache’s Hadoop.
Aside from threading on single machines, it’s feasible that tasks could be multi-threaded on many machines (distributed). The key to being successful with distributed computing is to truly understand the “work” problem or task. Developers need to think beyond the cube. How can we use another computer’s JVM, OS, or process stack?
Can you explain in basic terms how garbage collection works in JVM or .NET?
System level languages such as C, Objective-C, C# are compiled into machine code and the developer is responsible for memory management. Java was designed to handle that for the developer, however an understanding of garbage collection is needed because Java memory management isn’t perfect. It’s good programming practice to be aware that Java objects are not destroyed immediately upon exit of a method. Java will cleanup and destroy these objects using it’s garbage collection mechanism that comes with the Java Virtual Machine (JVM). When your Java program runs, a process (OS-level process with process id) called “java” will be running. This is the JVM or execution environment for all Java programs. The JVM will run bytecode created by your Java compiler and translate the bytecode into machine instructions specific to your microprocessor. As the various Java threads are executed, a lower priority thread will come in and out of the execution pointer and destroy Java objects, freeing up random access memory (RAM) periodically.
Since Java does not immediately free object memory, sometimes this lack of resource is noticeable to the system user. Java developers should be aware of this and try to reduce the number of instanced Java objects in parent object methods. Simplification and refactoring should be part of all code reviews.
PARP Inhibitors
Usually my local paper is fairly quiet, but today it caught my attention. I’ve tried to keep up with the technology used to kill cancer cells for quite some time. My wife had breast cancer for 16 years and recently passed away because of it. Chemotherapy has been the choice of weaponry against cancer because most treatments would signal cell-death hence no renewals (loss of hair, anemia, etc.). A new drug group is now being tested called Poly (ADP-ribose) polymerase or PARP inhibitor. This drug targets enzymes that help DNA correct itself. All of our body’s cells contain DNA or genetic code that provides instruction like a computer program for the cell during replication so that it is made “exactly” like the cell it’s made from. Cancer cells tend to grow more rapidly and their DNA is somehow incorrect. The PARP Inhibitor acts to target the cancer cells and attempt to correct the DNA causing the cancerous cell growth.
The trials for PARP Inhibitors is exciting because scientists know that the answer to eradicating cancer is to stop the hidden bug within our DNA or fix the DNA once we know someone has cancer. Current chemotherapy uses a technique called apoptosis where the drugs trigger the cells to kill themselves. Apoptosis is a type of cell death where the cell uses a set of programmed events (genetics) to cause its own demise. This technique used is most effective on cells that use apoptosis to heal themselves such as skin, hair, stomach lining, etc. And, of course it also works with cancer cells that grow rapidly. Personally, I’m not a big fan of current treatments because while it lengthens the patient’s life, it does not heighten or enhance the quality of one’s life. In fact, the second chemotherapy drug, Abraxane, my wife used was supposed to be very mild for the effects of nausea and she was hospitalized 3 times for nausea that lasted about 5 days each time. Abraxane is however a second effort treatment where other treatments have failed.
The PARP Inhibitor trials are a welcome sign that the research community is looking at other solutions to this problem. You can follow the trials by going to clinicaltrials.gov and typing PARP inhibitors in the search box.
The Benefits of a Continuous Build
Introduction
Developers today are bombarded with articles and blog posts about Agile development. There are books on the subject and plenty of consultants to share with you these agile practices. It’s a buzzword and it’s way overrated. Before they were marketing agile as a way of life, I had the opportunity to work for Newport News Shipbuilding and we were an agile team before the publicly marketed practices made famous by Alistair Cockburn and Scott Ambler. And, we were not so much agile as we were efficient. Efficiency creates effective lines of tested quality code and we wasted very little time during our coding phases.
Our efficiency was brought about by a very well-controlled software versioning system (CVS) and a custom continuous build system. I’ll quickly address the version control system and then focus on the benefits of a continuous build.
The version control system is a versioned and protected storage system for software that represents snapshots of the codebase throughout the project until the codebase is ready for a software release. The key here is that throughout the life of this project, our goal is to maintain a buildable codebase at all times. If each developer takes ownership in the project and promises to never check in a source file that would break the build, we’re golden. That’s too much to ask, but assume that the codebase is being kept in pristine condition.
The continuous build system will periodically checkout the codebase from the version control system and perform a compile and build of the software. If anything goes wrong, the continuous build system will notify all stakeholders and inform them that the build was unsuccessful. What do you think happens now? Well, the code gets fixed and quickly. The developer didn’t break his promise, he just made a mistake. We’re all human. The benefit to the continuous build is that the build gets fixed quickly. And, the problem was not that the build was broken but that the software was in error.
Quality is a perception. Quality software does not mean that the software is always perfect. This perception of quality comes when the software is released or the project is completed and the project team knows that the codebase has been continually tested and built successfully. And, this success should take into account that various small issues have caused the builds to fail but things were always easily and quickly fixed.
Scenarios
No Continuous Build
Usually the development group that does not utilize a continuous build, also does not use version control. However, I’ve seen some small projects that use version control but feel that the continuous builds are a waste time. Usually this stems from some management level that cannot see the ROI for implementation of the continuous build system. Days can pass and build problems, unknown to management, never get fixed. And, what happens if an impatient market or other business indicator deems for an early release? A broken build will delay the early release. And, it may take some code check-in and extensive investigation to determine truly what’s wrong?
Happiness is a Continuous Build
Welcome to true euphoria and great happiness. The development team that has a continuous build system in place knows that everytime a developer checks in a new code module or a revision to an existing one, the entire repository is normally checked out to a location remote to the repository (could be the local build machine). The code is built there and packaged into a deployment or software release. If everything is successful, no one even knows that the CPU in the build machine even warmed up. If something fails, usually everyone knows and the message spreads quickly. Nobody stresses out. We see in the build log that the helloworld module is the culprit. “Isn’t that Joe’s module?” “Yes, call Joe and have him check.”
Joe quickly spots the problem and checks in a fix. The build system checks out the code again and does another build. This time it’s perfect, all tests pass and the deployment archive was created.
Pros
A continuous build system will allow no isolated pockets of development. It is a very transparent system. Build errors are communicated immediately. This creates a keen sense of urgency and these errors are eliminated quickly. Management can take comfort in knowing that the build will always produce a packaged product that has been compiled, built, and tested once the project is underway.
Cons
There is a cost to implementing the continuous build sytem. And, human resource is required to implement the product and maintain it. This is however the only negative aspect that opposes the huge benefits of having a continuous build system.
Conclusions
A continuous build system will bring about a huge improvement in the transparency of the project’s codebase. Also, the codebase will quickly evolve into a packaged product that can be released for demonstration much earlier in the lifecycle of the project. I purposely wanted to show the benefits of a continuous build system and not go into anything specific. I think many people get excited about a particular product or open source download and their focus is on the features and not about the more important change from not having a system to having one and using it continuously (no pun intended).
Copyright Cape Henry Technologies Inc. 2010, All Rights Reserved.
Version Control Management
Introduction
Software projects come about because of the need for desktop or web applications to perform tasks for business. Many times these tasks are part of a larger business project. Every software project consists of some collection of textual software or scripts. This textual instruction is either compiled into an executable binary, packaged as a compressed deployment, or placed on a web server for direct interpretation. The instructional materials (code or script) are extremely valuable and change constantly over the course of time. Also, as the development team grows, this source code base can grow exponentially and will never be static again. And, across an enterprise, this moving mass of important documents should be managed centrally. If the enterprise consists of .NET and Java development groups, then at least the repositories should be centralized for each of these camps, i.e. the .NET and Java groups each have their own central repository. It is feasible, however for the .NET and Java groups to use the same source code repository.
Prerequisites or Considerations
There are several prerequisites and considerations for the implementation of source code management. The prerequisites will consist of server(s) for the repository hosting and software to manage the access, delivery, and committals. The server(s) will provide hosted access for the development staff via some port listener over the network. Each software versioning control product will have its own detail requirements for the server hosting. The overall requirement should be the implementation of an enterprise version control system.
A written process for the management of source code artifacts will be needed before anything is put in place. A clear understanding of the SCM product is not enough. This process should contain high-level instructions that show how multiple developers will work with their repository and how they will resolve conflicts. This step is critical. It is advised that you follow the successful model of other projects. You can find this information using Google searches. Do your homework, this is very important to the success of your project. Also, another option is the contractor vehicle. A contractor can be hired for the short term task of setting up your development environment using various technology stacks. This is somewhat time-consuming for developers are not already highly skilled in the use of these software tools, hence the contractor vehicle.
Planning and Choices
The first steps to planning an enterprise source repository would be to determine the exact number of projects within the enterprise and then estimate the disk space needed to store them all in one centralized repository. Extra space would also be required to account for growth and to host the software product. A good estimate would be 2 times the size of the entire collection of projects. Always be prepared to grow the file system or migrate to another quickly.
Next, determine your needs and choose an enterprise version control system. Consider the versioning model first. There are really three basic models. These are the file system model, lock-modify-unlock model, and copy-modify-merge model. Every source control versioning system employs one of these models. /p>
The file system model is really inefficient because it would never record versions. Every change would be a revision to the file in the repository or file system directly in this case. And, users changes would not be merged. Users would have to communicate frequently and even pass changes between each other and not through the so-called source repository itself. The second committer would overwrite any changes that had just been checked in. This system should never be mistaken for a true versioning control system. This model limits the decision now to one of two models.
The lock-modify-unlock model is used by some source control systems to keep users from modifying each other’s work. In a perfect world there would be no need for developers to change each other’s files as long as their work was properly managed. It still almost impossible to assign developers specific files on a project. Under the lock-modify-unlock method, if someone has a file locked or “checked out”, another developer cannot checkout the file to make changes. This user must wait for the “locked” user to unlock or “check in” the file before he can lock and modify the file. Visual SourceSafe employs this model.
This model is more restrictive that the copy-modify-merge model. E.g. if Robert checks out file A and forgets to check it in or worse, loses the file and the hidden file that works with the repository, and Susan needs file A right away, an administrator is needed to unlock the file so that Susan can modify it for a Friday afternoon build. Also, does anyone know what Robert was working on and do we care? We just overrode his checkout and allowed Susan to modify the file without talking to Robert first. It’s common for one developer to be working on one method and another working on another method. That’s okay, but for this model that doesn’t work well at all.
The copy-modify-merge model is the best choice for version control of textual source code files. The lock-modify-unlock model is too restrictive in the event that a developer has a file checked out and he’s on vacation or cannot otherwise be contacted. This model works better because it actually operates in reverse. The repository is not aware of any new or revised work until the commit is made. The only failure would be in the event that another developer has huge changes to a file and has not committed those changes. It makes sense to update frequently, build successfully, and commit often. The key is to never commit work that puts the build at risk. Many development teams use a continuous build process where an isolated build is run everytime anyone commits a change to the repository. This build should always be successful but in the event of a failure, notifications are sent out via email. Communications will then occur, the code will be corrected, and the fix for the broken build committed. This is a very well managed process. And, it does require good communications.
Resources
Resources that are needed for the versioning control system would be for continuous use and maintenance. Be sure that adequate disk space is allotted and disk space is available for growth. Backups of the repository are critical and necessary to the security of the repository in the event of disaster. The backup process is an important resource that’s integral to the safety of the enterprise’s source code base.
Once a version control system is in place, an administrator is needed for the management, backup, and maintenance of the source repository. For single project instances a developer may serve as an administrator, however enterprise solutions would require a dedicated administrator. A business could train an existing employee as the repository grew in size and project number. That might be an economical option. Many developers have extensive knowledge of the various source control versioning systems because they use them during their development. One could hire a developer/versioning administrator.
Specific Choices
While GIT is now becoming more popular with the independent contractors and developers than Subversion (SVN), SVN still stands to be the best corporate choice for an open source solution. Here’s an executive summary from a Forrester report on Version Control Systems by Carey Schwaber. The entire document was proprietary and is not available to the public (even though she’s talking about freely-available open source products).
“Some development teams need only simple version control, the base functionality of software configuration management (SCM) systems, to manage their application code. In the past many such teams have used the open source version control tool Concurrent Versions System (CVS), but CVS’ file-based architecture saddles it with many serious limitations. Subversion, an open source tool designed as a replacement for CVS, has been in development since 2000 and is now ready for mainstream adoption. Shops evaluating version control tools should put Subversion on their shortlists, and shops using commercial version control systems like Microsoft Visual SourceSafe should consider whether Subversion might meet their needs just as well. The availability of an open source tool without many of CVS’ pains will accelerate commoditization of the market for commercial version control tools. But while Subversion is a better tool than CVS, it’s still just a version control tool, and it shouldn’t be used in place of a full-featured SCM system.” … Cary Schwaber for Forrester
Cary’s last statement was a marketing one. You want to read on. And, you can if you pay up. She assumes that you need a full-featured SCM by the way she ends her last sentence. An enterprise can implement such a system and still use Subversion for it’s versioning control component. Commercial vendors are quick to assume that an enterprise needs a full-featured SCM system. This is entirely not true. Vendors of these products want to convince you that their integrated systems blend requirements, issues, versioning, documentation, management, etc. making development the focus and reducing the burden of trivial administrative functions. In fact, manually developed systems work fine too. A project could be completed successfully and never use an SCM tool.
Another document, “The Forrester Wave: Process-Centric Software Configuration Management, Q4 2005, also by Cary Schwaber, quite possibly paid for by IBM, is freely available to the public. It does not recommend any open source products. In fact, it does not consider any solution that isn’t company backed with a minimum of $25 million in total annual revenues. This document recommends an integrated IBM solution using all of their SCM products. Does this make IBM the better choice just because they meet the $25 million annual revenue minimum? Does the revenue minimum inherently represent worth and quality? I know this axiom not to be true.
IBM’s Clearcase is a versioning system just like Subversion, however they have several other products when installed that can be considered a full-featured SCM system. The IBM products have high licensing costs while Subversion alone is free. A full-featured SCM system is not needed for agile development methodologies. The IBM “need” is to market the purchase of their products so that your enterprise can complete the project successfully that would have failed had you not purchased their software. This is wrong. Many successful software development projects use incompatible applications for version control, bug tracking, and documentation. My personal recommendation for both the .NET and Java groups would be host Subversion’s version control system on Redhat Linux server(s), Atlassian JIRA enterprise issue tracking, and Atlassian Confluence enterprise wiki.
Cost of ownership can direct choices. License costs really don’t balance with administrative costs. Proprietary and open source solutions require trained administrators. Proprietary solutions come with steep licensing costs. Open source solutions generally are free, however security comfort is sometimes compromised. This is only due to the fact that the enterprise may have only recently considered open source alternatives. Open source is generally secure because it’s very dynamic and the source code is freely available to anyone, including vulnerability hackers.
Conclusions
Every IT enterprise creates textual artifacts that range from configuration scripts to computer language code. Every enterprise should maintain versions of these files. To do this the enterprise needs a central repository and versioning software. The most important factors that face the deciding enterprise should be model first, and cost second. Also, access to the repository is accessible to anyone that’s authenticated and authorized to look at it. Developers that only maintain code locally essentially hide their work from everyone. Source code should be shared. And, even if it’s not open source, it should be shared among similar language developers within the company for re-use if licensing permits.
I have equal experience with each of the versioning control systems. The copy-modify-merge model is my favorite and has been the least troublesome. I’m personally a command-line person and that’s why Git is my absolute favorite, Subversion or SVN second, CVS third, and Visual SourceSafe fourth. I have used Borland’s Starteam for 2 years with CIBER and absolutely hated it. Customizations were of no benefit to our project. Daily use of Borland’s product also required tweaking hidden files essentially proving that the product was unstable even though the license costs should represent high quality.
Copyright Cape Henry Technologies Inc. 2010, All Rights Reserved.
An AppFuse-like JSON-Flex Example
While I’ve been doing a little research, I actually created two working projects that demonstrate a JSON to Flex mashup. The Flex project will probably evolve into a complicated mess over time because I’ll use it for testing with an AppFuse instance hosted on my local machine. For now, however, I’m going to tag compatible versions so that those that want to take a look at it can get it to work easily.
The two projects are found on Github here: http://github.com/dlwhitehurst/appfuse-rest and http://github.com/dlwhitehurst/appfuse-flex-client First, download and build the rest example (tag v0.1-MASHUP) first. If you don’t see the tag yet, I haven’t done it but you can trust me that the latest commits work. I’ll tag tonight.
Once you successfully build a WAR file you can “mvn jetty:run-war” in a terminal and just leave it running. To see the Flex client in action you can just double-click on the main.html in the $project/bin-debug folder. That’s it! You should see a simple button and a datagrid. Push the button and the datagrid should load.
All of the source code is available in both projects. Check it out. The difficult part was getting the data to display in the datagrid. The Bindable declaration is what fixed my problem. I had read that even if the data (JSON) was parsed and visible as an Array, the data would not work with the mx:DataGrid object unless it was converted to an ArrayCollection object. I fumbled with that for a while then I started getting warnings about static types vs. dynamic components. I eventually found an example where [Bindable] was used just over a variable declaration for the ArrayCollection that would populate the mx:DataGrid and that worked! Here’s the main.mxml that does it all.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | <?xml version="1.0" encoding="utf-8"?> <!-- add license --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundGradientColors="[0xFFFFFF, 0xAAAAAA]" horizontalAlign="left" verticalGap="15" horizontalGap="15" > <mx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; import mx.controls.Alert; import com.adobe.serialization.json.*; import mx.collections.ArrayCollection; [Bindable] private var customersCollection:ArrayCollection; private function runService():void { getCustomers.send(); } private function resultHandler(event:ResultEvent):void { var rawData:String = String(event.result); var customers:Array = JSON.decode(rawData) as Array; customersCollection = new ArrayCollection(customers); } ]]> </mx:Script> <mx:HTTPService id="getCustomers" url="http://localhost:8080/customers.json" method="GET" resultFormat="text" result="resultHandler(event)"> <mx:request xmlns=""> <getCustomers>"true"</getCustomers> </mx:request> </mx:HTTPService> <mx:Button x="266" y="338" label="Get Customers" id="getCustomersButton" click="runService()"/> <mx:DataGrid id="cGrid" x="80" y="141" width="400" height="92" editable="false" enabled="true" dataProvider="{customersCollection}"> <mx:columns> <mx:DataGridColumn headerText="Id" dataField="id" /> <mx:DataGridColumn headerText="Name" dataField="name" /> <mx:DataGridColumn headerText="Phone" dataField="phone" /> </mx:columns> </mx:DataGrid> </mx:Application> |
Global Security for WebSphere Local within RAD
The key to global security for the instance of WebSphere running within your Rational Application Developer product is to keep the server security and RAD’s understanding of the security synchronized. To do this, always set or disable security first using the administrative console.
With Websphere running within the IDE, go into the security area and set or disable the security parameters. Once you are done, kill the admin console window or tab within Eclipse (RAD). Then select the server and shut it down. Once it’s down, you can right click and edit the server security properties.
If RAD or the server get out of synch with each other, it’s very possible you will not be able to shut down the server properly within the IDE. Open a terminal window and I’ll show the windows version here:
10 | ...\runtimes\base_v6\bin > stopserver server1 -username test -password test |
Installing RAD for Websphere as Non-admin User
This posting will document the best way to install and setup IBM’s Rational Application Developer (RAD) for Websphere as a non-administrative user. I’ll be editing this along as I do the install and prepare the documentation for a group of developers at a large state organization.
To get started you would obtain the CDs or the installation media from IBM. In our case, we have the full downloads for Rational Application Developer (RAD) 7.6 for System Z. I found an article online for 7.5 and some of the instructions are a little different. Also, some windows paths have been changed. Once you have the downloads (zips), extract them all in a directory (as a general user) e.g. c:\RAD76 (ours is RADz76). Check in the setup directory for another folder or directory called InstallerImage_win32. Next, check to see if a file called userinstc.exe exists there. If yes, let’s proceed.
You’ll now need to prepare a small .bat file to execute the user installer to install the IBM Installation (Product) Manager silently as a non-administrative user to the user’s profile instead of c:\Program Files. Here’s the .bat file needed. Remember that your paths may be different.
10 11 12 13 14 15 16 | echo off SET LOGDIR="c:\temp" SET INSTALLER="c:\RAD76\RD76_Setup\InstallerImage_win32" %INSTALLER%\userinstc.exe --launcher.ini %INSTALLER%\user-silent-install.ini -log \ %LOGDIR%\Installer.log echo on |
The above script can be run in a cmd terminal and will silently install the IBM Installation Manager under your user profile. Under my user profile “dlwhitehurst” I now have … \IBM\Installation Manager and \IBM\InstallationManagerInstaller. This installation script will also write an entry to your Start menu “My Installation Manager”.
The next part is a bit more difficult. Another .bat file is needed to run the installer to setup and install RAD 7.6 and create a default WebSphere profile for testing.
The actual RAD installation was a little more difficult because we had downloaded separate media into our install directory. The media consisted of …disk1 and …disk2. The second .bat file is here. It was run but was unsucessful. I’ll explain how to fix after the script listing.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | echo off SET ILOGSDIR="c:\temp" SET INSTLMGR="C:\RADz76\RDz76_Trial_Setup\InstallerImage_win32" SET RESPONSEFILE="c:\temp\responsefile-nonadmin.xml" del %RESPONSEFILE% echo ^<?xml version="1.0" encoding="UTF-8"?^> >> %RESPONSEFILE% echo ^<agent-input acceptLicense='true'^> >> %RESPONSEFILE% echo ^<server^> >> %RESPONSEFILE% echo ^<repository location='C:\RADz76\RDz76_Trial_Setup'/^> >> %RESPONSEFILE% echo ^</server^> >> %RESPONSEFILE% echo ^<profile installLocation='c:\dlwhitehurst' id='IBM Software Delivery Platform'^> >> %RESPONSEFILE% echo ^<data key='eclipseLocation' value='c:\dlwhitehurst'/^> >> %RESPONSEFILE% echo ^<data key='cic.selector.nl' value='en'/^> >> %RESPONSEFILE% echo ^<data key='user.help.option' value='remote'/^> >> %RESPONSEFILE% echo ^<data key='user.help.url' value=''/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.createProfile' value='true'/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.profileName' value='was70profile1'/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.profilePath' value='c:\dlwhitehurst\runtimes\base_v7\profiles\was70profile1'/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.enableSecurity' value='false'/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.username' value=''/^> >> %RESPONSEFILE% echo ^<data key='user.was.v70.password' value=''/^> >> %RESPONSEFILE% echo ^</profile^> >> %RESPONSEFILE% echo ^<install modify='false'^> >> %RESPONSEFILE% echo ^<offering profile='IBM Software Delivery Platform' version='7.6.0.20090930_1054' id='com.ibm.rational.developer.systemz.v76.trial'/^> >> %RESPONSEFILE% echo ^</install^> >> %RESPONSEFILE% echo ^<preference value='%USERPROFILE%\IBM\SDPShared' name='com.ibm.cic.common.core.preferences.eclipseCache'/^> >> %RESPONSEFILE% echo ^<preference value='true' name='com.ibm.cic.common.core.preferences.http.proxyEnabled'/^> >> %RESPONSEFILE% echo ^<preference value='false' name='com.ibm.cic.common.core.preferences.http.proxyUseSocks'/^> >> %RESPONSEFILE% echo ^<preference value='localhost' name='com.ibm.cic.common.core.preferences.http.proxyHost'/^> >> %RESPONSEFILE% echo ^<preference value='9080' name='com.ibm.cic.common.core.preferences.http.proxyPort'/^> >> %RESPONSEFILE% echo ^<preference value='30' name='com.ibm.cic.common.core.preferences.connectTimeout'/^> >> %RESPONSEFILE% echo ^<preference value='30' name='com.ibm.cic.common.core.preferences.readTimeout'/^> >> %RESPONSEFILE% echo ^<preference value='0' name='com.ibm.cic.common.core.preferences.downloadAutoRetryCount'/^> >> %RESPONSEFILE% echo ^<preference value='true' name='offering.service.repositories.areUsed'/^> >> %RESPONSEFILE% echo ^<preference value='false' name='com.ibm.cic.common.core.preferences.ssl.nonsecureMode'/^> >> %RESPONSEFILE% echo ^<preference value='true' name='com.ibm.cic.common.core.preferences.preserveDownloadedArtifacts'/^> >> %RESPONSEFILE% echo ^<preference value='false' name='PassportAdvantageIsEnabled'/^> >> %RESPONSEFILE% echo ^</agent-input^> >> %RESPONSEFILE% %INSTLMGR%\userinstc.exe --launcher.ini %INSTLMGR%\user-silent-install.ini -input %RESPONSEFILE% -log %ILOGSDIR%\RadInstall.log echo on |
When the above script was run, an error message was given stating that the silent install cannot be performed because of multiple media disks. Normally with a GUI install, the installer can stop and request that the user switch CD’s. A silent install is programmatic and therefore cannot interact with the user via a graphical environment. The silent install is running in terminal. The two disks are zipped and the paths in both disks begin with RADz76/.. This allowed me to extract the disks into RADz76 and now the disks were combined under one directory RADz76. I re-ran the installation script and it worked.
There are problems with the above script that did not affect the installation. The profile information would be fine for a RAD for WebSphere installation. What I found was that WebSphere was not embedded with the RAD for System Z install. I have installed RAD for WebSphere and both version 6 and version 7 were present. The RAD for System Z only contains support for WebSphere 6.
Database Use with Rails
I really like Ruby on Rails for personal application development. If I had more time, I would probably invest more of this time learning Rails to actually help small businesses develop applications. Anyhow, I have created an accounting program called “Books” that is really easy to use and I wanted to describe here how the database is used and created.
When you create your Rails application a ton of code is written for you. The key database file is called database.yml and it’s found in the project tree at /config/database.yml. Here’s my file.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | # Licensed by Cape Henry Technologies Inc. # Cape Henry Technologies Inc. licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SQLite version 3.x # gem install sqlite3-ruby (not necessary on OS X Leopard) development: adapter: mysql encoding: utf8 database: books_development pool: 5 username: root password: socket: /tmp/mysql.sock # adapter: sqlite3 # database: db/numbers_development # pool: 5 # timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: mysql encoding: utf8 database: books_development pool: 5 username: root password: socket: /tmp/mysql.sock production: adapter: mysql encoding: utf8 database: books_development pool: 5 username: root password: socket: /tmp/mysql.sock |
Notice the database name is “books_development” for all database schemas. I commit the project files to Github and tag versions. I then download a zip of the version I want and explode it into a directory called “books-2010″ and I then change the database.yml file database names to “books-2010″. This way when I run the application and actually use it, the production data is safely handled by this application source code I downloaded.
When I make the application public, one would download the version, and issue the following commands in the project root directory.
20 21 22 | rake db:create <enter> rake db:migrate <enter> rake db:seed <enter> |
The seed functionality is very cool in it’s own right. You can make up a file to preload reference data or in my case, initial accounts for your chart of accounts. Here’s a copy of seeds.rb and it’s found at /db/seeds.rb.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | # This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Major.create(:name => 'Daley', :city => cities.first) general_ledger = GeneralLedger.create([ { :company_name => 'Acme Mousetraps Inc.', :address1 => '123 Pleasantville Road', :address2 => '', :city => 'Omaha', :state => 'Nebraska', :zip => '76499', :registered_agent => 'John Doe', :tax_id => '1234567890' } ]) accounts = Account.create([ { :acct_no => '100', :acct_name => 'Cash', :acct_type => 'A', :balance => '1000.00', :general_ledger_id => '1' }, { :acct_no => '102', :acct_name => 'Accounts Receivable', :acct_type => 'A', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '109', :acct_name => 'Capital', :acct_type => 'A', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '103', :acct_name => 'Supplies', :acct_type => 'A', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '104', :acct_name => 'Equipment', :acct_type => 'A', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '202', :acct_name => 'Accounts Payable', :acct_type => 'L', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '202', :acct_name => 'Tax Payable', :acct_type => 'L', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '300', :acct_name => 'Drawing', :acct_type => 'L', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '500', :acct_name => 'Rent Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '501', :acct_name => 'Supplies Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '502', :acct_name => 'Books Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '503', :acct_name => 'Meals Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '504', :acct_name => 'Auto Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '505', :acct_name => 'Misc Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '506', :acct_name => 'Electric Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '507', :acct_name => 'Internet Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '508', :acct_name => 'Liability Insurance Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' }, { :acct_no => '509', :acct_name => 'Medical Insurance Expense', :acct_type => 'E', :balance => '0.00', :general_ledger_id => '1' } ]) |
The third rake command you issue, finds this files and pre-loads your database with this data.