Practically Agile
Using Agile in less-than-perfect situations since Y2K
Using Agile in less-than-perfect situations since Y2K
Yesterday, I posted my technique for installing Informix on a Mac. Well, it turns out I wrote just a bit too soon. What I had was indeed working, but only for the “dbaccess” tool that ships with Informix. Trying to connect from a Java (JDBC) application failed.
Thanks to Eric Herber’s comment on that post, the PDF it mentions, and a bit more research, I was able to make a two significant updates to my installation.
Reading through the PDF, it notes that the informix user and group are required in order for things to work properly. Examining my install, it seems that the IDS installer tried to create the informix group, but somehow assigned it the same group ID as the _lpoperator group. I believe _lpoperator is the group of people who can use the Mac’s printers. Regardless, it wasn’t the informix group that it should have been.
Important! If you don’t understand what is meant by user and group here, my best advice would be to get someone who does to help you. I don’t want to insult anyone, but making changes to the things I am about to mention could render your machine unusable. Here be dragons!
To fix this issue, I had to do two things. First, create the informix group and make it the informix user’s “primary” group. Second, I had to change the group ownership of everything in my Informix install directory from _lpoperator to the new informix group. The PDF talks about using the Workgroup Manager that is available in the OS X Server Admin Tools. I will let you read that for the details except to say that the correct URL for acquiring the tools depends on the version of OS X you have. Regardless, the URL in the PDF is outdated, as is one I found in a search on MacOSXHints. The best means I have found is to go to the Apple Support site’s Advanced Search, enter “server admin tools”, select the radio button to match all keywords, use the drop-down to restrict the document type to “Downloads”, and pick the version you want from the results. I am far from certain, but it would make sense to pick the one closest to your version of OS X.
Once you have the Server Admin Tools download, it is a simple, and typical Mac install. Once installed, you can run the Workgroup Manager tool more or less as stated in the PDF. Do not skip the step that asks you to select “Show All Records” from the “View Menu”. This may be “Show System Records” depending on the version of the tool. If you know a little about Unix user management, the tool is fairly intuitive. If you know a lot about Unix user management, you may prefer the command line tools that can do the same thing. Regardless, I simply had to create the informix group and make it the informix user’s primary group.
It is worth noting that if I had created the informix user and group using this tool before running the installer, I probably would not have had the _lpoperator nonsense nor would I have had to do the next step: changing the group ownership of all the files in my Informix install.
To change the group ownership, I went back to the command line and did the following:
$ cd /Applications/IBM/informix $ ls -l total 11656 drwxr-xr-x 3 root staff 102 Aug 15 2008 CSDK drwxr-xr-x 5 root staff 170 Aug 15 2008 DBLD drwxr-xr-x 3 root staff 102 Aug 15 2008 ICONNECT -rw-r--r-- 1 root staff 5904 Aug 14 2008 README.html drwxr-xr-x 7 root staff 238 Aug 15 2008 SERVER drwxrwxr-x 4 informix _lpoperator 136 Jan 13 15:50 aaodir drwxr-xr-x 109 informix _lpoperator 3706 Jan 13 15:54 bin ... -rwxr-xr-x 1 root _lpoperator 29713 Aug 14 2008 uninstallserver $ sudo chgrp -R informix aaodir ...
Note: The “…” on line 11 means there were a lot of other entries. The one at the end means that I repeated that “sudo chgrp” for all of the files and directories that had group ownership of _lpoperator.
That group information was annoying and tedious to fix, but it was not really the problem. If you recall from the earlier post, there are some environment settings that need to be loaded. One points to a file that is very important to enabling clients to connect to the server: INFORMIXSQLHOSTS. The whole purpose of the file is to define the mechanisms by which clients can connect, this means whether they must be using shared memory space or can use sockets and what port they use to connect. The one created by the installer for the demo database has a single line that looks like this:
demo_on onsoctcp yoda.local 9088
The first is the dbservername and is correct for the demo database. The second is a three-part string that identifies how clients can connect. In short, “on” means a regular database server (short for on-line as in OLTP maybe), “soc” means sockets as opposed to “shm” for shared memory, and “tcp” means the network protocol. So, this seems right as well. The other two entries are the machine hostname and the port. However, although my Mac is named “Yoda” (yes, I’m a Star Wars geek), that is not listed in the /etc/hosts file. I changed this to “localhost” which is in the hosts file. Finally, that last entry is meant to be the service name from the /etc/services file, not the port number. To figure out how to change this, I used the following command:
$ cat /etc/services | grep Informix sqlexec 9088/tcp # IBM Informix SQL Interface sqlexec 9088/udp # IBM Informix SQL Interface sqlexec-ssl 9089/tcp # IBM Informix SQL Interface - Encrypted sqlexec-ssl 9089/udp # IBM Informix SQL Interface - Encrypted
My final file still contains one line, which looks like this:
demo_on onsoctcp localhost sqlexec
And now, everything is working smoothly. Whew!
Tags: informix, install, mac, osx, snow leopard
Update: I had some problems connecting to Informix via Java. Also, the process below led to an issue with the “informix” user’s group settings. I have created a “part 2″ post to detail what happened and how I managed to fix it. Please read that before using these instructions to perform your own install.
I have recently started a project with a group that uses Informix as the database. To set up my development environment to match production as closely as possible, I have installed IDS for Mac. The instructions that you can find on the web caused me some difficulty. There is a video available from IBM that would be great, but it seems to be outdated slightly. (Viewing it may still give you some benefit, so you can find it here.) To save myself time in the future if other Mac users need to join the project, I have documented what I believe to be the final process here.
Caveats:
If you try this out and find some things that don’t work or ways to make it faster or easier, please let me know in the comments. I will happily incorporate them.
One quick formatting note, when command examples are given, the “$” at the beginning of a line is in place of the command prompt. By default in the Mac Terminal app, this is usually of the form “hostname:current_directory username$”. If you copy and paste the commands, remove the “$” and the space after it.
kern.sysv.shmmax=4398046511104 kern.sysv.shmmin=1 kern.sysv.shmmni=512 kern.sysv.shmseg=512 kern.sysv.shmall=1073741824 kern.sysv.semume=10 kern.sysv.semmsl=87381 kern.sysv.semmnu=87381 kern.sysv.semmns=87381 kern.sysv.semmni=87381 kern.maxfiles=2147483647 kern.maxfilesperproc=40000 kern.maxvnodes=150000
$ sysctl kern.sysv.shmmax kern.sysv.shmmin kern.sysv.shmmni kern.sysv.shmseg kern.sysv.shmall kern.sysv.semume kern.sysv.semmsl kern.sysv.semmnu kern.sysv.semmns kern.sysv.semmni kern.maxfiles kern.maxfilesperproc kern.maxvnodes
$ sysctl -w
And copy the key-value from the list above (ex. kern.sysv.shmmax=4398046511104)
$ . /Applications/IBM/informix/demo/server/profile_settings
$ dbaccessdemo
$ dbaccess
$ sudo chown informix informix
$ su - informix
$ cat /Applications/IBM/informix/demo/server/profile_settings
$ cd ~ $ vim .profile
$ . /Applications/IBM/informix/demo/server/profile_settings
$ oninit $ onstat - IBM Informix Dynamic Server Version 11.50.FC2DE — On-Line — Up 00:00:09 — 41756 Kbytes
$ onmode -ky</blockquote> $ onstat -</blockquote> shared memory not initialized for INFORMIXSERVER ‘demo_on’
Tags: informix, install, mac, osx, snow leopard
At the risk of this becoming a bile blog, I have another Java rant. It has been a long-standing tradition (12 years?) among Java developers to cry out that the date implementation in Java is pretty terrible. So, it’s not just me
As a bit of history, the folks at Sun (soon to be Oracle) tried to fix this by all but requiring that Date objects be wrapped with Calendar objects in JDK 1.1. They couldn’t just fix the date implementation directly because of another long-standing tradition: new Java versions must be backward-compatible with previous versions. Regardless, this fix has long been considered a kludge at best, but most of us learned to live with it. Preamble out of the way…
I was working with someone today who had a Calendar object. They wanted to compare it with another object to see which was earlier. So, they called Calendar.after(Object). Makes sense right? Only this method returned false even when the other object was definitively a representation of a time after that represented by the Calendar object. This seemed odd to the developer in question.
The observant among you may have noticed that I did not say they were comparing with another Calendar object. They were, in fact, comparing against a Date object. Knowing that, I immediately suspected the problem. A quick trip to the API docs showed me this gem:
Returns whether this
Calendarrepresents a time after the time represented by the specifiedObject… if and only ifwhenis aCalendarinstance. Otherwise, the method returnsfalse.
So, rather than throwing an IllegalArgumentException or having the method specifically only take a Calendar object, this method and the corresponding before(Object) method both just return false when you send in… anything else. So Calendar.after("dates in Java suck") returns false.
There are no good reasons for this that I can think of, so I went to the Bug Parade. There, I found a few tickets that were marked as fixed or otherwise closed. However, this is still obviously a problem, right? Refining my search, I found what I think is the most recent one. It is marked as “Closed, Will Not Fix”. Why? Here is the relevant part of the comment:
It’s hard to change the implementation at this point. Please use compareTo(Calendar) added in 1.5.0.
I’m sorry, can’t we at least deprecate things that are this broken? Do we not do that after the heckling caused by deprecating 60% of the methods in Date?
A follow up question… Where is the replacement library? We had java.nio, why not create a new java.date? For that matter, why hasn’t a third party library really taken off here? My suspicion is that JPA integration is the main challenge. Especially since, in addition to the problem of them having the same class name, java.sql.Date extends java.util.Date.
Maybe I’ll try out Joda Time or another 3rd party replacement. Does anyone know how their Hibernate sub-project works in the field? (Update: The goal of JSR-310 is actually to get Joda Time into core Java. It had been tentatively scheduled for Java 1.7. A quick look around shows that there was some struggling to get it completed and tested for inclusion. I was not able to determine an outcome. Anyone know?)
I’ll try to make my next post about something more positive.
Tags: bug, calendar, date, java, rant
The last few months have been pretty mixed for me as a programmer. I have been a Java developer since the 1.0 days circa 1996-1997. (Netscape IFC anyone?) For me, it was a great change from C and C++. That’s twelve-ish years with most of my professional work in one language. For the last couple of years, I have been doing a bit more project and people management and less programming. When I have done programming, it has been largely Ruby, HTML/CSS, Javascript and even some C#.
Therefore, it was with a great deal of happiness that I was able to take on a much more developer-oriented role in my latest Java project. I was back in the groove. There were some annotations I had to learn or re-learn, but they mostly made sense. I was concretely producing value again rather than just enabling others to do so.
Over time, I found myself stumbling over difficulties that were entirely Java-centric. I kept running into problems with Generics. Java reflection was a morass of generics and class-casts. I found myself every single day having to say, “I hate Java Generics.”
// a sample usage of generics
// based on a real usage in my current project
Map<Class<ReasonableClassName>, ReasonableClassName> objectByType =
new HashMap<Class<ReasonableClassName>, ReasonableClassName>();
// pre 5.0
Map objectByType = new HashMap();
I was never a fan of the Generics proposal for Java 5. It is just overly verbose as the example above shows. The Java 5 version provides type safety, but at what cost? Fortunately, back then, I was able mostly to ignore this. I only really used generics when using collections, and I tend to wrap those in more domain-friendly objects. That practice also meant I didn’t really need generics in the first place, but c’est la vie. I was happy enough.
In the current project things are somewhat different. I am building upon legacy code, using a lot of collections in a single class, and using a lot of reflection. I found APIs that were inconsistent in their use of Generics. For example:
// from java.lang.Class
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) {
// ...
}
public Constructor<?>[] getDeclaredConstructors() {
// ...
}
Note that when getting a single declared constructor, it returns a properly specified constructor that will create something of the type of the class. However, if I want the full list of constructors, the array returned now doesn’t know what type the created objects would be. There is a reason for this: having a “genericized” array is “bad”. Don’t ask me why. Folks much more familiar with the generics implementation struggle to understand the reason for this.
Regardless, it means I need to cast the result. Is that not what generics were supposed to save me from? This also could lead (depending on the context) to entirely unnecessary type checks or even a compiler warning for “unchecked type cast”. In short, what I have found is that for every benefit generics provide, there are multiple hoops to jump through or other problems that detract from it. Yes, some of this is caused by the implementation and not the concept, but that makes me think worse of Java, not better.
There is also a push to add more “safety” to the language through annotations and other means. Java cannot take more overhead pushed into doing simple things. I am far from the only one to think this. As an example, see this post from almost a year ago.
I am pretty fluent in Java (sans generics) at this point. It is by far the language I know best. However, I now realize that while Java may continue to be what I am paid to do, my personal first choice will have to be something else. Using the language is too much work; it is too cumbersome. I like Ruby already, but maybe I’ll delve deeper into Scala. At least both of them run on the JVM.