Networking and Software28 Aug 2008 12:05 pm

This query returns all objects.

#include <stdio.h>

#define LDAP_DEPRECATED    1

#include <ldap.h>

const  char *base = “dc=application,dc=company,dc=com”;
char loginDN[] =”cn=Manager,dc=virtualcenter,dc=vmware,dc=int”;

#define TRACE()  printf(”%s:%d\n”, __FILE__,__LINE__)

/*TODO free memory*/
void handle_search_result(LDAP *ldap,  LDAPMessage *result){
char  *attr;
LDAPMessage *entry;
BerElement *ber;
char **values;

printf(”Entries =  %d\n”, ldap_count_entries( ldap, result ));

for (entry = ldap_first_entry(ldap, result);
entry != NULL;
entry = ldap_next_entry(ldap, result))
{
printf(”dn=(%s)\n”,ldap_get_dn( ldap, entry ));

for (attr = ldap_first_attribute(ldap, result, &ber);
attr != NULL;
attr = ldap_next_attribute(ldap, result, ber))
{
printf(”\t%s\n”,attr);

values = ldap_get_values(ldap, entry, attr);
int   i =0 ;
int len =  ldap_count_values(values);
for (i =0; i < len; ++i){
printf(”\t\t%s\n”,values[i]);
}
}
result = ldap_next_message(ldap, result);
}
}

int execute(){
printf(”Running\n”);
LDAP *ldap;
char *uri = “ldap://localhost”;
int rc = ldap_initialize(&ldap, uri);
if (LDAP_SUCCESS != rc){
printf(”error:%s\n”,  ldap_err2string(rc));
return rc;
}

rc =  ldap_bind_s(ldap, loginDN, “vmware”, LDAP_AUTH_SIMPLE );
if (LDAP_SUCCESS != rc) goto error;

char *attrs;
LDAPMessage *res = 0;
rc =  ldap_search_s (ldap,base,LDAP_SCOPE_CHILDREN
,”(objectclass=*)”,0,0,&res);
if (LDAP_SUCCESS != rc) goto error;

printf(”number of results = %d\n”,ldap_count_messages(ldap,res));
int attid = 0;
char * attr;

handle_search_result(ldap,  res);

goto cleanup;
error:
printf(”error:%s\n”,  ldap_err2string(rc));
cleanup:
ldap_unbind(ldap);
return rc;

return  0;
}

int main(){

return execute() ? -1 : 0;

}

Networking and Software28 Aug 2008 09:40 am

After a few days beating my head against OpenLDAP’s C API, the only thing I can think is that the developers don’t want you to use it.

All of the simple functions, the functions that are in all of the sample code out there, has been deprecated:

  1. ldap_bind and it’s ilk are gone with the exception of ldap_sasl_bind and ldap_sasl_bind_s.
  2. ldap_init, and ldap_open are gone, although ldap_initialize still exists.

What seems to be going on is an attempt to push people to use SASL: The (not so) Simple Authentication and Security Layer that abstracts away the differences between Kerberos, Radius, and other full fledged authentication and authorization mechanisms.

The problem here is that the most common  application for using LDAP is for authenticating users.  It doesn’t matter that you “shouldn’t” do this according to the established literature.  If you are stuck talking to Active DIrectory, LDAP is your primary tool.

The LDAP_Result api makes sense from an object oriented perspective, but man, is that a lot of function calls just to iterate through a list.  For example, to process the effect of calling ldap_sasl_bind you have to call:

  1. ldap_result
  2. ldap_first_message
  3. ldap_parse_result
  4. ldap_free for each value allocated by ldap_parse_result
  5. ldap_next_message
  6. ldap_freemsg

The problem here is they are trying to be objected, but stopping short of actually returning vtables.  I suspect I could just look at the LDAPMessage structure and get the same result.

I think the choice of SASL is somewhat suspect as well.  I would much prefer it if they used PAM.  If you are going to make use of a flexible authentication mechanism, go with the dominant one.

I admit that I am not an expert on LDAP things, and that perhaps I am missing something.  But trying to get the C equivalent of

ldapsearch -H “ldap://localhost” -LLL -x -b  ‘dc=application,dc=domain,dc=com’ ‘(objectclass=*)’

Should not take several days.

Database and Software and shell15 Aug 2008 12:35 pm

I’m looking at the SQL Scripts that create and modify the database for VPXD. Specifically, I am looking at the oracle version stats[123] scripts. They included a query that uses the “OVER” keyword and I have not found a decent description of what this keyword does. This is the query:

SELECT
st.counter_id AS COUNTER_ID
,v_time_rowid AS TIME_ID
,ST.STAT_VAL AS STAT_VAL
,DENSE_RANK()

OVER (PARTITION BY ST.COUNTER_ID ORDER BY SM.SAMPLE_TIME DESC) AS DENSE_RANK
FROM vpx_sample_time1 sm,vpx_stat_counter sc, vpx_stat_def sd, vpx_hist_stat1 st
WHERE sm.rollup_counter=to_number(to_char(v_start_time_id)||to_char(v_cnt))
AND st.time_id = sm.time_id
AND st.counter_id=SC.COUNTER_ID
AND SC.STAT_ID=SD.ID
AND ((SC.DEVICE_ID =v_null_device_id and v_stat_rollup_level<3) or (v_stat_rollup_level>=3))
AND SD.STAT_LEVEL<=v_stat_rollup_level
AND SD.ROLLUP_TYPE=3)
WHERE DENSE_RANK=1

;

The one description of the Over command I have found has come from the Microsoft website:

“Determines the partitioning and ordering of the rowset before the associated window function is applied”

OK, so it is a union of two types of functionality: partitioning and ordering. The queries I am looking at use both. Let’s start with partitioning:

PARTITION BY
Divides the result set into partitions. The window function is applied to each partition separately and computation restarts for each partition.

The window function in this place must somehow refer to DENSE_RANK. To me this looks like it is possibly trying to insert a subselect into the overall select. Here is how MSDN defines DENSE_RANK. I’d like to reiterate that these are Oracle functions I’m trying to understand, and Microsoft is doing all the work explaining them. When I tried executing this SQL Query in SQLPLUS via the Oracle 11 instant client, it balked:
SQL> 2 3 4 5 6 SQL> SP2-0734: unknown command beginning “OVER (PART…” - rest of line ignored.
SQL> SP2-0734: unknown command beginning “FROM vpx_…” - rest of line ignored. It parses fine when I do it as part of a plsql stored procedure.

Time to dig out the slightly larger guns: I picked up a copy of the SQL Cookbook by Anthony Moliaro from Our Friends in Sebastopol, CA. This covered both DENSE_RANK and the OVER keyword.

Over, it turns out, is one of a new set of functions added to SQL 2003 that the Standard calls Windowing functions. This means they operate on a subset of the results returned from the outside query. The best example I saw showed if you are selecting all employees from all departments, and next to each one you wanted to show how many employees were in that department, you could use count(*) with an over clause that specified PARTITION by department. This example is in the Cookbook.

DENSE_RANK () tells you how many rows come before the current row in some ordering scheme. The over clause is used to define that ordering scheme. If two rows have the same rank, they have equivalent values according to DENSE_RANK. For instance, if we have five people with five salaries, their DENSE_RANK of salaies will be 1 through five, highest to lowest. If the top two salaries were identical, top rank would return 1,1,2,3,4.

OK, so it looks like the original query wants to use DENSE_RANK on a subset of the returned rows of the query. The window will be defined by this portion of the clause: PARTITION BY ST.COUNTER_ID

And the order within this window will be determined by: ORDER BY SM.SAMPLE_TIME DESC

OK time to get serious about playing:

I’ve learend a little biut since the above frustrations trying to run the stored procedure. Here’s what I do now:

run sqlplus. For me this is

/home/adyoung/apps/oracle/instantclient_11_1/sqlplus adyoung/adyoung@10.17.195.159/DRORACLE

Now make it so anything I print to the screen is visible:

set serveroutput on

Load my sql file in and execute it.

get myfile.sql

/

OK, I have a development method. To print debugging output:
DBMS_OUTPUT.PUT_LINE(’Text Here’);
And we can debug. In the time honored tradition of always moving from success, I comment everything out but a simple output statement. In this case, I know that the real code uses a variable for the rollup level, so my File (minus commented out section, looks like this:
create or replace procedure stattest
is
v_stat_rollup_level int;
begin
v_stat_rollup_level := 2;
dbms_output.put_line(’Value: ‘ || TO_CHAR(v_stat_rollup_level));
end stattest;
Which executes using the above method. Now I start adding in parts of the SELECT.
SELECT st.counter_id AS COUNTER_ID FROM vpx_hist_stat1 st;
Of course, it hates this. When I load it into sqlplus I get:
Warning: Procedure created with compilation errors.
Of course, in order to see these compilation errors, I have to jump through a couple more hoops:
SQL> set arraysize 1
SQL> set MAXDATA 6000
SQL> show errors procedure stattest
LINE/COL ERROR
——– —————————————————————–
6/1 PLS-00428: an INTO clause is expected in this SELECT statement
So I add a variable called maxcounter in the declare section and modify my select:
SELECT
max(st.counter_id) into maxcounter
FROM
vpx_hist_stat1 st;
dbms_output.put_line(’Maxcounter: ‘ || TO_CHAR(maxcounter));
And I have a procedure that executes and does something. On to the rest of the select. After several iterations of trial and error, I have the SQL query wokring as a cursor. I’ve now figured out even a better way to work. I’ve modified my file like below, and can now cat it into the sqlplus interpreter:
set arraysize 1
set MAXDATA 6000
set serveroutput on

create or replace procedure stattest
is
v_stat_rollup_level int := 2;
maxcounter int := 0;

CURSOR MYCURSOR is SELECT
st.counter_id as COUNTER_ID,
st.STAT_VAL as STAT_VAL
FROM vpx_sample_time1 sm,
vpx_stat_counter sc,
vpx_stat_def sd,
vpx_hist_stat1 st

WHERE
st.time_id = sm.time_id
AND st.counter_id=SC.COUNTER_ID
AND SC.STAT_ID=SD.ID
AND SD.ROLLUP_TYPE=3
AND SD.STAT_LEVEL<=v_stat_rollup_level;

begin

open MYCURSOR;

FOR recname in MYCURSOR
LOOP
dbms_output.put_line(’Value: ‘ || TO_CHAR(v_stat_rollup_level));
END LOOP;

dbms_output.put_line(’Maxcounter: ‘ || TO_CHAR(maxcounter));

end stattest;

/

show errors procedure stattest

.

OK, I am going to bail here.  This post has been half written for a while, and is not going to get completed anytime soon.  I think I’d vote “Over” as something that would be useful in the next rev of postgres, if only for simplifying porting from Oracle.

Software and Sysadmin and shell14 Aug 2008 11:31 am

The following script, when run on a RPM based system, tells you what licenses your application might trip by linking with other code.  You have to  set $MYEXE to som path to an executable.

for LIB in `ldd $MYEXE | sed -e ’s!.*=>!!’ -e ’s! (.*!!’` ; do rpmquery –whatprovides $LIB ; done | grep -v “any package” | sort -u | xargs rpmquery –qf %-30{NAME}:%{LICENSE}”\n

Here is a sample run for perl:

glibc                         :LGPL
perl                          :Artistic or GPL

Note that this is only for the linked files that are registered with RPM.

Networking and Software13 Aug 2008 01:41 pm

The following code will convert an ethernet MAC address to the comparable  IPv6 link only address.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

int main(int argc, char** argv){

int addrlen = strlen(”0000:0000:0000:0000:0000:0000:0000:”);
char* out = malloc(addrlen);
char * outorig = out;

memset(out, 0, addrlen);

char* addr =    “00:0c:29:20:4e:e3″;

if (argc > 1){
addr = argv[1];
}else{
fprintf(stderr,”usage %s macaddr\n”,argv[0]);
exit(-1);
}

int len = strlen(addr);

if (len > 18){
printf (”String too long\n”);
exit(-1);
}

int i ;
int col_count = 0;
unsigned char current = 0;
for (i = 0; i < len; ++i){
char c = addr[i];

if (0 == c){
break;
}else if (’:’ == c){
switch( col_count ){
case 0:{
sprintf(out,”fe80::”);
out += strlen(out);

unsigned short c2 = ( current | 0×02 );
if (c2 == current){
c2 = current & 0xcf;
}
sprintf(out,”%02x”,c2);
out += strlen(out);
}
break;
case 2:{
sprintf(out,”%02xff:fe”,current);
out += strlen(out);
}
break;
default:
sprintf(out,”%02x”,current);
out += strlen(out);

if (col_count % 2){
sprintf(out,”:”);
out += strlen(out);
}
}
++col_count;
current = 0;
}else if ((c >= ‘a’) && (c <= ‘f’)){
current *=16;
current += ( 10 + c - ‘a’);
}else if ((c >= ‘A’) && (c <= ‘F’)){
current *=16;
current += ( 10 + c - ‘a’);
}else if ((c >= ‘0′) && (c <= ‘9′)){
current *=16;
current += ( c - ‘0′);
}
}

sprintf(out,”%x”,current);
out += strlen(out);
printf(outorig);
return 0;

}

Philosophy and Software07 Aug 2008 01:09 pm

My  previous article talking about dependency injection had the dependencies registered via an explicit function called from main.  This may give the wrong Idea about how to register dependencies.  Here is a much better approach, but with a solution that is compiler specific.

Applications on Linux comply with a one of a limited number of different formates.  The older style is referred to as  a.out, the default file produced by gcc if no -o target is given.  More common now is the Extensible Loadable File format, or elf.  An application can link libraries in one of three ways.  The tight coupling comes from static binding, where all dependencies are resolved before the executable file is written.  Typically, this is linking together files with extension like .a or .o depending on format.

Second is library loading done at execution time.  Here , a version of the library is registered with the system, and resolved at process execution time.  These libraries have extension of .so for ’shared object’ although they usually have version numbers after the so.  To see the libraries that an executable depends on, run the command ldd.

The third type of binding is done after the process hits main, and is a deliberate function call by the application ‘dlopen’.  This also loads .so files, but  all linking and symbol resolution is done via function calls.

The mechanism allows the library to specify  a block of code that the linker runs whenever one of these forms of loading occurs.  The current incarnation of this mechanism looks like this:

void __attribute__ ((constructor)) my_init()

The name of the function does not matter: I have called mine my_init but it cane be anything, although you should account for name clash, especially if you wish to call the function again later in your program.  There is a corresponding function called upon cleanup.

void __attribute__ ((destructor)) my_fini(void)

The earlier names for these functions were _init and _fini, and I suspect many compilers support this, but it has been deprecated in gcc to use that form.

Since this gets called at application load time, and before main, it is a logical place to place our registration code.  Note that you can make no assumptions about what has been loaded or initialized at this time.  A modified version of the bindings.cpp code from the previous article would look like this:

extern “C”{
void __attribute__ ((constructor)) register_all_bindings(){
static bool not_yet_run = true;
std::cout << __FUNCTION__;

if (not_yet_run){
std::cout << “:Registering”;

supply<A>::configure();
supply<A,1>::configure(destroy);
supply<B>::configure(make);
supply<B,1>::configure();
supply<C>::configure(makeC,dropC);
not_yet_run = false;
}
std::cout << std::endl;
}
void __attribute__ ((destructor)) binding_fini(void){
std::cout << __FUNCTION__ << std::endl;
}
}

I have added a little bit of logging to show when these function are called.  It is probably safe to put a  simple boolean “lock” around the initialization code since this is run before any pthread create type code, and thus is guaranteed to be single threaded, but this assumption may not stay true in the future, so beware.

The code I have above registers all the classes in a single chunk.  This is not really interesting, nor is it likely how an application would be written in the “real world.” Instead, each subsystem would be responsible for registering their set of factories.  This code should not attempt to create any objects, as they may not be loaded yet.

Sysadmin and package management06 Aug 2008 11:06 am

A couple times I’ve had to answer to question:  What licenses ship out with our system?  If you are shipping something on top of RedHat (in our case, CENTOS) or SuSE ( I haven’t tested this) you can generate a list of package names and licenses with the following command.

rpmquery -a –qf %-30{NAME}:%{LICENSE}”\n”

Philosophy and Software and compsci30 Jul 2008 06:14 pm

One goal of object oriented programming is to encapsulate functionaliy within a class.  If one class requires another in order to collaborate on a larger process, the programmer must deal with the wiring up of the two classes.  Much has been writen about the correct way to do this in various object oriented languages.  The term “Inversion of Control” and the related concept of “Dependency Injection” have become part of the common language of software development, at least in the Java world, due to projects like Pico/nano container, The Spring framework, and earlier efforts inside J2EE and ATG Dynamo.  These frameworks make use of the introspection mechansims in Java to create instances of classes based on demand criteria.

One drawback of the introspection mechanism is that it works outside of the type system.  A programmer can write code that compiles, but is semantically incorrect.  The only way to test this code is by running it. Since C++ lacks the introspection mechansim of Java,  this approach cannot be ported to C++.  Hoever, C++ Has a much richer system for developing type based programs anyway:  templates.  Many of the techniques from Alexandrescu’s Modern C++ Design can be linked together to build an inversion of control mechanism that is type safe.  An added benefit is that the mecahnism suffers from none of the introspection overhead of the Java approach, and thus can be used inside performance critical code.

The general approach is to register a construction and destruction function for a given class with a factory for that class.  The factory is a templatized class  that supports partial template specialization, allowing multiple definitions for a class.  The factory functions are capable of calling other factory functions, to fetch and create dependencies for the class in question.  For instance: Let’s  define a class S which   stands alone.  Additionally, we define class D which depends on class S.

In C++ code we would traditionally write something like:

S* s = new S();

D* d = new D(s);

However, there may be an instance of ’s’ already created.  Thus we are linking the creation and usage of the classes together.

There is much code out there classes like ‘D’ actually have the knowledge of how to create or fetch ’s’.  The classes ‘S’ and ‘D’ at least start by requiring something external to wire them up. This is intentional, as the method of creation of ’s’ is a policy decision that is outside the scope of ‘D’.  In the example above, the policy is hard coded to be a ‘new’.  IDeally, we would separate this policy from the usage of the classes.

I am now going to introduce a templatized class called Supply.  A supply is a class that maintains references to factories and instances produced by those factories.  The policy of how to create and destroy these objects are registered with the Supplies when the appication is initialized like this:

Supply<D> register(createD,destroyD);

Where createD and destroyD are function pointers.

We can be tricky and omit the functions for create and destry, in which case the supply is smart enough to just call the constructor and destructors, but that doesn’t make for a very easy to understand example. In another file we can register how to create and destroy S

Supply<S> register();

In order to fetch and instance of type S we call:

S* s = Supply<S>.fetch();

This code can exist inside the createD function which would look like this:

D* createD(){

S* s = Supplys<S>.fetch();

return new D(s);

}

So far we have divided the construction logic from the usage by adding a single function to create the object graph on demand.  The fetch function can be made smart enough to check if it has an instance available and, if so, to return that instance instead of calling the create function.

The level of Inversion of Control described thus far is fairly paltry, and would not be a valuable addition to most programs.  It lacks at least two things to be truly useful.  FIrst, there needs to be a way to distinguish between two different instances of the same class.  Even more important is the ability to scope those instances to a particular subdivsion of the application.  There are two techniques we can use to implement these features: either by calling a different function for each instance, or passing in a parameter that is used to distinguish between the instances. The key tool for selecting between two functions is partial template specialization.  Specifically, we want to use a primitive value to distinguish between different creation policies.  For instance, suppose an application requires several different database schemas.  One pool is for online transaction processing (OLTP), one is for content management, and one is for integration with a legacy system.  A class named DatabasePool controls connections to each database.  We would need to register each DatabasePool separately:

Supply<DatabasePool, DBPOOL_OLTP> register(createOLTPPool, freeOLTPPool);

Supply<DatabasePool, DBPOOL_CONTENT> register(createContentPool, freeContentPool);

Supply<DatabasePool, DBPOOL_LEGACY> register(createLegacyPool, freeLegacyPool);

Then when an class requires a DatabasePool to perform it’s work, it would register to resolve the  dependency  with:

Supply<DatabasePool, DBPOOL_LEGACY>.fetch()

To scope an instance of a class to a specific portion of the application requires understand the application type.  The types of applications written in C++ range from small to large.  Here is an incomplete list:

  • Embedded programming
  • handheld wireless device applications
  • Desktop GUI applications
  • System tray applets
  • HTTP based applications
  • streaming media network services
  • TELNET style connection based network services
  • Asynchronous messaging for systems integration
  • Data intensive super computing (DISC)
  • Massively parallel message passing interface (MPI) Supercomputing tasks.

The scopes for each of type of application is going to be somewhat different.  In embedded programming for really small devices we can probably make most objects global.  Something as complex as an dependency injection may be more than the device can handle.  Working up the stack, we come across applications that require threading, and that may be handling multiple users at the same time.  This adds a new requirement: our dependency injection mechanism must be thread safe.  Here we can lean upon the lessons learned by many people that have been building enterprise applications in Java for many yeakmrs.  In the J2EE stack, in ATG Dynamo and now in the Spring framework, objects can be scoped globally, per application (assuming multiple apps run in the same container), per session, and per http request.  This is a pretty good breakdown of scopes, and applies to many of the application types besides HTTP.  For instance, a TELNET server would have one session per socket connection , and divide up the stream into smaller sequences that map to requests.  An asynchronous messagin protocol would not have sessions, as state is contained completely inside the messages, but certain patterns like scatter/gather might have scopes  that span multiple messages. Applications at the smaller and larger ends of the spectrum have a similarity in that the tasks tend to be the only thing running on the machine, and thus there is less of a need to distinguish between session, application and global scoping.

I’m going to describe the  HTTP model with the hope that applying it to other types of applications will be done fairly similarly.  THe scopes from shortest to longest are : request, session, application, and global.  When the network server starts running, the first global objects get initiated.  These in turn activate the applications.  One of these objects will listen for network connections and accept incoming requests.  The first such request will force the creation of a session.  Once the request is handled and the response is sent, the request object is freed along with all of its corresponding objects, while the session  and associated objects remain in the application, usually on a timer that will free them after some period of no activity.  The session is uniquly identified with a cookie sent with the response, and sent back to the server with each subsequent request.  The Request object will then associate itself with that session. Once the hierarchy is established from request up to session, all object resolution requests are fulfilled via a chain of responsbility.  The application specific code should only resolve via Supply<T>.fetch(Request).  If the object requested is not registered at the request level, the call is forwarded on to Supply<T>.fetch(Session), and then on to  Supply<T>.fetch(Application), and finally to Supply<T>.fetch() which resolves globally.  Failure to resolve globally will trigger an exception.

The onus is upon the application developer to correctly register the scope of requested objects.  Each object will then be created upon first demand, and reused until the lifetime had been completed.  For example a DHCP server that recieves a packet containing a ClientMACAddress will parse the field from the packet when first accessed, and then subsequently will use the parsed object until the DHCP request has been sent, at which time the ClientMACAddress will be freed.

Here is a sample implementation.

http://adam.younglogic.com/resolver/

I had origianally meant to expand the scope of this discussion to talk about entities stored inside a database, but quickly realized that it was at leas as complex as the discussion above.  If the Entire database can be held in memory at once, you can make them global objects.  Anything more than that requires a complicated caching scheme.  That will be a separate article

History and Philosophy30 Jun 2008 06:28 pm

Massachusetts has one of the best public school systems in the country. It has been top in the country before, and was rated fourth last I checked. California, which has one of the largest economies in the world, is ranked in the bottom quintile.  I was lucky that my parents moved from California back to Massachusetts before I was born.  My wife and I made the same decision shortly after our son was born. Education, and public education are important to us.

The field of Computer Science seems to be getting dominated by people from China and India. This influx of brainpower to the United States is great for us. But why don’t we see more Engineers that come up out of the US educational system?

It is tough to be a smart kid in this country. While geek-chic has come in to vogue, and internet based social organization has become the norm, I wonder if things have really changed where it matters the most: at the elementary school level. Large class size, focus on the problem kids, shrinking budgets, and now the focus on standardized testing all makes it difficult to tailor the classroom experience to the kids that attend it. I was fortunate in that my elementary school there was a large enough population of smart kids that I still had a decent sized group of friends. I was a talker, and wanted to be involved in what was going on. This lead to a label of “Loquacious” and a lot of punishment assignments for talking during class. I did so poorly in the classroom that if I didn’t have the knack of doing well on standardized tests, I would have been labeled learning disabled. Things didn’t turnaround for me academically until Junior High School, when we were grouped by ability. I don’t think my experience is unusual.

India and China have a few things that lead to their current rise in technological prominence. A Huge population means that there are more students of all ability levels, including superstars. Low local wages provide the incentive to move overseas to where jobs pay better. Both countries have a strong tradition of education. India has the added benefit of a strong English tradition.

I’d like to reiterate that this isn’t a Xenophobic anti-h-1-b rant.  I’ve worked with too many amazing people from other countries to think that the influx is anything but helpful to the USA.  The question I want answered is what we can do to increase the number and quality of engineers produced by our education system.

The funnny thing is, the best students don’t make the best engineers.  I wonder how many superstar engineers were lost due to an inability to deal with school.  I know of at least two women who left the Calculus track in High School that were significantly better at Math than I was.  I was no superstar, but I did manage to get a 3 on the AP Caluculus A test.  Maybe it was too high pressure, maybe it was too boring, but both of those answers indicate something that could be modified by the teachers.  It was too many years ago for me to know what really happened.

Army and Uncategorized20 Jun 2008 07:39 am

West Point has started letting Grads that are recruited by Pro sports teams go be recruiters, and play pro ball.  This has caused much heated discussion, especially amongst my fellow alumni.  I initially wrote this as a response to an email discussion, but decided to sit on it for a while and ruminate.  This is really more of a collection of my thoughts at the time than a coherent essay.

It seems particularly stark in contrast to the classmates that are headed to Iraq. Would people feel as strongly about the matter if we were not sending people into harms way?

Also, is admissions the only reason that success in Army Sports, Football in particular, is important?

What about the rest of us that “did our time” and are now sitting out this conflict? Yeah, we played Army for our total of 8 years Active and Reserve. For many, it was a great experience that has lead to success later in life. Are we any less guilty of avoiding our Duty? How about the guy that “only” goes Signal Corps as opposed to going in to a combat Arms, or that goes Artillery to avoid Infantry? There always is a way that someone who goes less than the full HUAH can be said to be shirking.

Is it really doing our Country any good to be sending our Grads over to Iraq? I think most people would say that it is not cut and dried: some yes, some know, many I don’t knows. So why is it so important that these kids go to Iraq instead of playing Football? Is it really just a question of paying your dues?

Maybe the best way this kid can server his country is by being a kick-ass footballer, getting the name of West Point up in front of the country, and help to raise the awareness of civilians that we even have service academies. Maybe He’ll have a two year career, get cut, and end up back on Active Duty. Maybe he’ll be such a kick ass recruiter that he’ll fill the Army’s quota single handedly. Or maybe the Army wasted money in training him, and it was a mistake to send him to the NFL.

Is keeping a bunch of barely post adolescents isolated from the rest of civilization for four years the best way to prepare them for the officer corps? Does the Army get as much bang for it’s buck vie the Service Academies as it does Via ROTC? Sure West Point has produced it’s share of generals, but would those same people be great generals if they had gone ROTC? Would the opportunities in the Army be different if the Largest block of officers in the Army didn’t come from the same school? I have no idea if what we are doing makes sense or not. I know I gained a lot and gave up a lot by going to West Point. I’ll never know what I would have gained if I had gone another route.

Letting Cadets go professional  will allow the coaches to recruit players who, as Seniors in High School think they have a chance to play pro ball. Most College Football players want to go pro, but few are chosen. I suspect that a good portion of these players would make decent soldiers. So Army Football gets a better team, and good but the less-than-great ball players now have the chance of a career as an Army officer.

Many kids enter West Point as an option, and only develop the drive to be Army officers while being at West Point. I suspect that this is one of the most important roles that West Point plays in support of our Officer corps.

Next Page »