<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-833450457622807111</id><updated>2011-12-13T22:00:19.947-08:00</updated><category term='Design'/><category term='Workflow'/><category term='Performance'/><category term='Java'/><category term='Server Script'/><category term='Date/Time'/><category term='Database'/><title type='text'>Journal of a Siebel Hacker</title><subtitle type='html'>Essays and notes about Siebel development by Mike M. Lin, a former Software Engineer at Siebel Systems and seasoned Siebel Consultant.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-1954737990719740365</id><published>2010-12-01T13:07:00.000-08:00</published><updated>2010-12-01T13:32:47.067-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server Script'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>What's wrong with profile attributes?</title><content type='html'>As a general rule, we shouldn't allow developers to use profile attributes.  Looking back, I've probably used about 1 profile attribute a year, to accomplish some pretty edgy (read: hacky) things.  People normally use them to pass data around like from a business component to an applet or a from the server to the browser.  Here's why they're a bad choice...&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;&lt;b&gt;Profile attributes have no scope, and no namespace.&lt;/b&gt;  Profile attributes are set at the session level so changes made in one piece of code can inadvertently affect code in other areas.  The fact that there are no namespaces makes the problem worse, because your chances of accidentally using a name someone else used are greater (although you could come up with some namespace scheme).&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;&lt;b&gt;Profile attributes screw your ability to debug.&lt;/b&gt;  Because you can't find all the places your profile attribute might be set or unset, debugging becomes much tougher.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;&lt;b&gt;Profile attributes screw your ability to refactor.&lt;/b&gt;  For the same reasons that your ability to debug is screwed, so is your ability to refactor.  One of the basic things you need to be able to do when refactoring is finding all the places you used variable x.  Well if variable x is a profile attribute, good luck!&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;&lt;b&gt;Getting a profile attribute from the client is costly. &lt;/b&gt; Not everyone understands this.  Your profile attributes do not exist in the client.  So when you try to read them from browser script, Siebel needs to do a round-trip to the server to get it.  That's a round-trip for each profile attribute you get or set.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;In short, if you think you need to use a profile attribute to accomplish something, &lt;i&gt;think again!&lt;/i&gt;  If you still think you need a profile attribute, hit yourself on the head and &lt;i&gt;think again!*&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;
&lt;/i&gt;&lt;/div&gt;&lt;p&gt;&lt;div&gt;&lt;i&gt;* The same advice pretty much applies for shared globals as well.&lt;/i&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-1954737990719740365?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/1954737990719740365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2010/12/whats-wrong-with-profile-attributes.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/1954737990719740365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/1954737990719740365'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2010/12/whats-wrong-with-profile-attributes.html' title='What&apos;s wrong with profile attributes?'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-8321563991578239765</id><published>2010-07-21T16:02:00.000-07:00</published><updated>2010-07-21T16:21:39.109-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Java Data Bean Performance</title><content type='html'>I'm not supposed to be working on Siebel anymore, but something keeps pulling me back to do odd jobs.&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;One of my coworkers was complaining about the slow performance when integrating with Siebel using the Siebel Java Data Bean.  He was just creating some buscomp records and setting a bunch of field values along the way.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;I'm not very familiar with the Siebel Java Data Bean, but my theory is that each buscomp operation (NewRecord, SetFieldValue, SetFieldValue, SetFieldValue, etc) was triggering a round trip to post changes to the server.  There aren't a lot of hard rules in my book for improving performance, but avoiding the network is one of them (avoiding the database is another).  [Can anyone confirm my theory that the Java Data Bean is heavy on posting changes?]&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;So how can we avoid the network in this case?  Two ideas immediately come to mind.  Without giving it away, one of them still uses the Siebel Java Data Bean, the other uses a different solution altogether.  Either of them would allow you to create a bunch of new records all in a single round-trip.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;Can you guess what I'm thinking of?  Any additional ideas that may help here?&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;p&gt;&lt;div&gt;[We did a quick POC and were able to get a 90% reduction in execution time with one of these approaches]&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-8321563991578239765?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/8321563991578239765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2010/07/java-data-bean-performance.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/8321563991578239765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/8321563991578239765'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2010/07/java-data-bean-performance.html' title='Java Data Bean Performance'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-8213889583485869937</id><published>2010-04-30T09:34:00.000-07:00</published><updated>2010-05-10T09:33:04.593-07:00</updated><title type='text'>Could not open/read file: C:\sea77\client\local\sse_data.dbf</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ZqD0HGgm6Ps/S9sHguQaXGI/AAAAAAAAA6k/0lMcY5wOozg/s1600/could_not_open_sse_data_dbf.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 68px;" src="http://2.bp.blogspot.com/_ZqD0HGgm6Ps/S9sHguQaXGI/AAAAAAAAA6k/0lMcY5wOozg/s200/could_not_open_sse_data_dbf.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5465970831498304610" /&gt;&lt;/a&gt;Do you get a popup error when you start up your computer that says "Could not open/read file: C:\sea77\client\local\sse_data.dbf"?  If you do, I bet it takes a heck of a long time to start up your computer too.  I haven't run into this problem for quite sometime, but I just got a new machine and a clean install of Siebel 7.7.6.2 (client).  I run into this problem every time I make a clean install but for some reason I can't seem to remember how to fix it right away.  It bothers me enough that I thought I'd post a solution to it here.  It's easy.&lt;div&gt;&lt;ul&gt;&lt;li&gt;In Windows, go to Start &gt; Run, and type "services.msc" in the Run window to open your services console.&lt;/li&gt;&lt;li&gt;Find the service named "Adaptive Server Anywhere - siebel_local"&lt;/li&gt;&lt;li&gt;Right click the service and select Properties from the context-menu&lt;/li&gt;&lt;li&gt;In the Properties window, change the startup type to "Manual"&lt;/li&gt;&lt;li&gt;Do the same for the service named "Siebel QuickStart Service"&lt;/li&gt;&lt;li&gt;Click Apply, then OK&lt;/li&gt;&lt;/ul&gt;This disables the auto-startup of the SQLAnywhere server that looks for your local database.  Another fix is probably to re-point your Local data source to an existing DBF file, or to drop a DBF file into the expected directory, but I don't really need this feature on startup, so I just like to disable it.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;There you go.  Enjoy your two minutes back at every startup.


&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-8213889583485869937?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/8213889583485869937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2010/04/could-not-openread-file.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/8213889583485869937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/8213889583485869937'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2010/04/could-not-openread-file.html' title='Could not open/read file: C:\sea77\client\local\sse_data.dbf'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ZqD0HGgm6Ps/S9sHguQaXGI/AAAAAAAAA6k/0lMcY5wOozg/s72-c/could_not_open_sse_data_dbf.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-3583366138489419099</id><published>2009-04-23T14:24:00.000-07:00</published><updated>2009-04-23T15:05:27.027-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Server Script'/><title type='text'>Workflow vs. Server Script</title><content type='html'>There's a lot of advice out there that says to use declarative solutions whenever possible and turn to scripting as a last resort only.  Hell, it's the basis of Siebel's technical document "Declarative Alternatives to Siebel Scripting".  I believe in using straight Tools configuration as much as possible, but there's one thing I'm not yet sold on: Using workflow processes in lieu of scripted business services for complex actions.

&lt;p&gt;I used to believe what I heard, that workflow processes were superior to scripted business services - but then I decided to evaluate it for myself.  There are advantages and disadvantages to each approach, and I'll get to those later.

&lt;p&gt;What originally sold me was the argument that workflow processes performed more strongly than server script because they did not have the overhead of a script interpreter.  The argument usually goes something like this, "Workflow processes run the compiled C++ code directly, so are faster than scripted processes that must be interpreted."  Well newsflash: Workflow processes also need to be interpreted.  Siebel did not build your workflow into their product, did they?  You described it using a tool, and that description must be interpreted at runtime.  Yes, compiled C++ is used to interpret your workflow processes.  And compiled C++ is also used to interpret your scripts.

&lt;p&gt;Which interpreter is faster?  Which engine loads faster?  I ran some tests to find out.  The results show that the two were very comparible when performing the exact same operations.  If there were any differences, they were negligible.  My test updated the amount of a single revenue record.  Each process (scripted and workflow) did one query and one update.  After warming up the OM, each process completed in 57 milliseconds on average (which included the time to invoke each via a driver script).

&lt;p&gt;What I did notice was that because workflow processes were not as descriptive as script, and you sometimes needed to do more work to accomplish the same task.  For instance, when I extended the test to update multiple revenue records, it took the scripted version 1 query and 21 writes to update 21 records, while the workflow processes needed 22 queries and 21 writes.  How did that affect the results?  The scripted process averaged a reasonable 500 milliseconds while the workflow process chugged along at 865 milliseconds on average.

&lt;p&gt;So the results seem to say that workflows are just as fast as scripts when the performing the same operations, but the inflexibility of workflow processes can lead to algorithms that are less than ideal performance-wise.

&lt;p&gt;Other reasons to like business services are that the development times are faster for various reasons.  The script debugging tools are more sophisticated, and starting your script debugger is typically faster than starting the workflow simulator - particularly if you need to deploy and activate a workflow subprocess before simulating.  And I don't think anyone would disagree when I say that scripts are far more flexible and powerful than workflow processes.

&lt;p&gt;So what reasons are there to like workflow processes?  For one, they can be deployed without an SRF.  I'm guessing that benefit has not nor will ever be realized by a large portion of Siebel customers.  One reason that I like is that their level of instrumentation is far superior to script.  The workflow monitor and logging events are far more useful in a production environment than any script built-in instrumentation for script (there is almost none).  That can be invaluable in getting a production issue resolved quickly, for a problem that would normally be hard to reproduce and research.

&lt;p&gt;In the end, I'm somewhere in the middle - but I'd have to say a bit closer to the script (read: dark) side.  What do you all think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-3583366138489419099?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/3583366138489419099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/04/workflow-vs-server-script.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/3583366138489419099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/3583366138489419099'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/04/workflow-vs-server-script.html' title='Workflow vs. Server Script'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-4968278900473527469</id><published>2009-03-12T12:47:00.000-07:00</published><updated>2009-03-12T14:43:21.220-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server Script'/><title type='text'>Extending eScript Objects</title><content type='html'>&lt;p&gt;There seemed to be a lot of interest in the post on &lt;a href="http://www.siebelunleashed.com/"&gt;Siebel Unleashed&lt;/a&gt; about the &lt;a href="http://siebelunleashed.com/abs-ati-framework-for-escript/"&gt;ABS (ATI) Framework for eScript&lt;/a&gt; (unrelated to Siebel's Appointment Booking System), which is some company's proprietary tool set used to perform repetitive tasks in eScript - some simple and some complex. A few examples given were: searching for the existence of a particular value in an array; accessing TheApplication() object; getting the field values of a record for which we know the Id. And doing those things in a consistent manner and using fewer keystrokes. What struck me is how well they integrated their framework with Siebel and core eScript objects.&lt;/p&gt;&lt;p&gt;I really believe in tool sets, and I'd like to see some Siebel hackers out there expand on the idea. How this tool set was built is not really obvious, so I'd thought I'd take a stab at it. Respecting the fact that the ATI Framework is proprietary, I won't give a whole lot of detail reverse-engineering the complex API calls I saw in the posts. However, I will show some basic techniques you can use to build your own framework using some simple examples. It would help to know a bit about objects and properties in JavaScript.&lt;/p&gt;&lt;p&gt;To keep the post relatively short, I'm not going to give any examples to validate that this stuff actually works. I'll leave that to you, because it's best to figure some things out yourself. If you're having problems, just know that I have successfully tested these concepts.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Is this value in the array?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Sometimes you have to search an array to see if a particular value exists. Nothing a little "for" loop can't take care of. But if you need to do this with any kind of frequency, why rewrite it every time? Also, what if a developer introduces a bug while trying to reimplement it? Write it once, make it work, and reuse it. Not only will you reduce your exposure to programming errors, but it will make your programs more succinct, and much easier to comprehend.&lt;/p&gt;&lt;p&gt;You can always add an application method that takes a reference to the array and the value you're searching for and returns a true or false, but I always wondered why this method wasn't part of the Array object to begin with. Let's go ahead and make it part of the Array object by modifying the prototype property to include a custom function. I put this in the "(declarations)" section of my application server script (which I chose because it's the first script I know of that's executed when the application starts):&lt;/p&gt;
&lt;pre class="jscript" name="code"&gt;Array.prototype.Exists = function (value)
{
  for (var i = this.length - 1; i &gt;= 0; i--)
    if (this[i] == value) return true;
  return false;
}&lt;/pre&gt;&lt;p&gt;Once this sets up you'll be able to see if the value "5 of spades" exists in your aCardDeck array: aCardDeck.Exists("5 of spades");&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Accessing the Application Object&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Ever get tired of typing TheApplication() every time you need to access an application method? Well those on the ATI Framework don't. It looks like they've reduced the application reference to some sort of global variable "TheApp", accessible from any object.&lt;/p&gt;&lt;p&gt;If I had a business component and wanted to make "TheApp" available from anywhere within that object, I could add a line like "var TheApp = TheApplication();" to the "(declarations)" section of the business component. But that means I'd have to add that line to every business component, which makes me angry. &lt;em&gt;You won't like me when I'm angry.&lt;/em&gt; So how can we avoid the maintenance hassle, and me turning into a big green monster?&lt;/p&gt;&lt;p&gt;What if we update the prototype of the business component object to include "TheApp"? That sounds like a good idea. Well unfortunately I haven't been able to figure out what the business component object/constructor is actually called. I'll do the next best thing, which is to add "TheApp" to all custom objects. The business component object must be derived from the Object class. So here's another addition to the application "(declarations)":&lt;/p&gt;
&lt;pre class="jscript" name="code"&gt;Object.prototype.TheApp = this;&lt;/pre&gt;&lt;p&gt;Remember, that "this" is the application object, since we're doing this from the application "(declarations)". This approach has the added benefit of enabling "TheApp" reference from all Siebel objects including business services, applets, and, yes, the application object itself. It surprised me that the application object was able to access "TheApp", since the prototype was modified after the application was already instantiated.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Adding a Custom Business Component Method&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Let's say, for some reason, you constantly find the need to get business component field values in uppercase characters only. Well here's what I added to the application "(declarations)" this time:&lt;/p&gt;
&lt;pre class="jscript" name="code"&gt;Object.prototype.GetFieldValueUpperCase = function (sFieldName)
{
  return this.GetFieldValue (sFieldName).toUpperCase ();
}&lt;/pre&gt;&lt;p&gt;Now if you have some bc "bcFoo", you can get the value for field "Bar" in uppercase characters by doing something like, "bcFoo.GetFieldValueUpperCase("Bar");" When this is called from a business component object, then all the references to "this" refer to that business component. &lt;/p&gt;&lt;p&gt;The unwanted side-effect here is that this method is enabled on all custom objects because we updated the prototype of the Object class. Since GetFieldValue() is only supported on business components, this will fail on any other object. So, if anyone finds the object/constructor names for any Siebel objects, please let that cat out of the bag. In any case, &lt;/p&gt;&lt;p&gt;I think you guys have had enough. Don't forget to let us all know if you find the object/constructor names for any Siebel objects. And if they're any new discoveries or breakthroughs out there, please comment about it. But for now, happy hacking!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-4968278900473527469?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/4968278900473527469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/03/extending-escript-objects.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/4968278900473527469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/4968278900473527469'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/03/extending-escript-objects.html' title='Extending eScript Objects'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-7349947693525415130</id><published>2009-02-13T20:03:00.000-08:00</published><updated>2009-02-17T11:19:17.725-08:00</updated><title type='text'>Siebel 8.1.1.0 on Windows Vista</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_ZqD0HGgm6Ps/SZZDxexISgI/AAAAAAAAAmU/fmcOTtwj6O0/s1600-h/No+translation+found+for+hiException_desc.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5302500128627116546" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 200px; CURSOR: hand; HEIGHT: 158px" alt="" src="http://2.bp.blogspot.com/_ZqD0HGgm6Ps/SZZDxexISgI/AAAAAAAAAmU/fmcOTtwj6O0/s200/No+translation+found+for+hiException_desc.jpg" border="0" /&gt;&lt;/a&gt;
So I decided to see what this Siebel 8 hype was all about. I downloaded all the necessary files from Oracle eDelivery, unzipped them, used the ImageCreator to build the network installation image (whatever that means), then proceeded to install Siebel Tools and Web Client.&lt;br /&gt;
&lt;br /&gt;
All of this on Windows Vista, mind you.  I had to run the installs as Administrator in Windows XP SP2 compatibility mode, otherwise, Oracle's Universal Install just disappeared as soon as files started copying.&lt;br /&gt;
&lt;br /&gt;
Well, the Tools installation completed, but failed to start. The Web Client just plain didn't install. The Web Client installation failed just after checking the system prerequisites, before choosing language packs.   When I attempted to continue, ignoring the error, no language packs appeared for selection.&lt;br /&gt;
&lt;br /&gt;
A little searching around brought me to this Oracle doc: &lt;a href="http://download.oracle.com/docs/cd/E11886_01/V8/CORE/8_1_1_Reqs_Platforms_RevA.pdf"&gt;"Siebel System Requirement and Supported Platforms, Version 8.1 Rev. A, January 2009"&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
"Table 7. Software Requirements for the Siebel Developer Web Client" lists Microsoft Windows XP Professional SP2+ as required software.  Does this mean that Siebel's latest release cannot run on Windows Vista?  I hope not.&lt;br /&gt;
&lt;br /&gt;
I hope that it's just something I did wrong, because it would be disappointing to learn that the Windows 7 Beta has already been released, and Siebel still hasn't found a way to get their Tools and Mobile Client to run on Windows Vista.&lt;br /&gt;
&lt;br /&gt;
If anyone knows how to get Siebel 8.1.1.0 running on Windows Vista, drop me a line, and  I'll update this posting.  Meanwhile, I'll be playing with 8.1.1.0 on my other machine which is running Windows XP SP2.  And FYI, it's running just fine on that.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-7349947693525415130?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/7349947693525415130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/siebel-8110-on-windows-vista.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/7349947693525415130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/7349947693525415130'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/siebel-8110-on-windows-vista.html' title='Siebel 8.1.1.0 on Windows Vista'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ZqD0HGgm6Ps/SZZDxexISgI/AAAAAAAAAmU/fmcOTtwj6O0/s72-c/No+translation+found+for+hiException_desc.jpg' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-6047791343936543474</id><published>2009-02-05T11:51:00.000-08:00</published><updated>2009-02-17T11:26:30.214-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Date/Time'/><category scheme='http://www.blogger.com/atom/ns#' term='Server Script'/><title type='text'>eScript Date Parser Bug</title><content type='html'>The Siebel eScript date parser does not correctly recognize dates in the 12AM hour in the format HH:MM:SS AM. This is a bug in some versions of the eScript engine, affecting server scripts, but not browser scripts - since browser scripts use the web browser's javascript engine. Check out the example below.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Siebel eScript (7.7.2.6 SIA [18372]):&lt;/strong&gt;&lt;br /&gt;
&lt;pre class="jscript" name="code"&gt;// incorrectly evaluates to noon
// "Sat Oct 18 12:00:00 2008"
new Date ('10/18/2008 12:00:00 AM").toString ();&lt;/pre&gt;
&lt;strong&gt;JavaScript engine from IE 6.0.2900.2180.xpsp_sp2_gdr.070227-2254:&lt;/strong&gt;&lt;br /&gt;
&lt;pre class="jscript" name="code"&gt;// correctly evaluates to midnight
// "Sat Oct 18 00:00:00 PDT 2008 12:00:00 AM"
new Date ('10/18/2008 12:00:00 AM").toString ();&lt;/pre&gt;
We just got a quickfix from Oracle for this nasty little bug we found, but the fix is on our private branch. So if this is affecting you, you might want to request it too. It took a few months between logging the SR and getting the patch delivered, so we had to work around the problem manually. We created a function to turn a string into a date object. In case you need it, here it is:&lt;br /&gt;
&lt;pre class="jscript" name="code"&gt;function StringToDate (sDateString)
{ // takes a date string, parses it using the
  // escript date parser, and returns it as a
  // date object. also works around a known
  // defect with the escript date parser
  // (siebel sr 3-765130491)

  var dt = new Date (sDateString);

  // address siebel product defect where
  // 12:XX AM dates get translated to 12:XX PM
  // in the date constructor
  if (/^[^:]*12(:\d{1,2}){0,2}\s*[Aa][Mm]/.test (sDateString))
  {
    // the time appears to be 12:XX AM,
    // so verify it
    if (dt.getHours () == 12)
    {
      // the hours are off, so fix it
      dt.setHours (0);
    }
  }

  return (dt);
}
&lt;/pre&gt;
I wonder if this problem occurs with date formats from other locales... In case you didn't know, I'm in the US.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-6047791343936543474?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/6047791343936543474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/escript-date-parser-bug.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/6047791343936543474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/6047791343936543474'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/escript-date-parser-bug.html' title='eScript Date Parser Bug'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-3792974877944391438</id><published>2009-02-03T15:02:00.000-08:00</published><updated>2009-02-17T11:27:38.167-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>Working with the Local Database</title><content type='html'>Us developers all have local databases we use to make changes before checking them into the server, right?  "No, I develop directly on the server," is not the right answer.  Sometimes it's useful to work directly with the local database to view or change data.  Here are some basics to get your started.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Logging In&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Siebel ships with a dandy SQL client you can use to log into your local database interactively.  The program is located in both the "..\tools\bin" and "..\web client\bin" directories, called dbisqlc.exe.&lt;br /&gt;
&lt;br /&gt;
Start this program and you'll enter directly onto a "Login" tab where you can fill in your username and password.  In the "Database" tab, specify the "Database file", pointing to the local database to which you want to connect.&lt;br /&gt;
&lt;br /&gt;
Once connected, running SQL statements is pretty self-explanatory.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Logging in as SIEBEL&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To make schema changes, log in as SIEBEL, using the same password as when you log in as yourself.  By default, the passwords are set to the same value when you get your extract.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Dropping a Column&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
After you delete a column from a table in the Siebel Repository, applying that change will not drop the column in your database.  You'll have to drop it manually using this command:&lt;br /&gt;
&lt;pre&gt;alter table &amp;lt;table name&gt; drop &amp;lt;column name&gt;
&lt;/pre&gt;
Notice that there is no "column" keyword before the column name.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Unlocking Projects&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When you get a locked project from the server, its copy remains locked on your local database as well.  If you want to locally test some changes in that project, you're going to have to forcibly unlock it using this SQL update statement:
&lt;pre&gt;update s_project set locked_flg = 'N' where name = &amp;lt;project name&gt;
&lt;/pre&gt;
&lt;span style="font-weight: bold;"&gt;Changing your Password&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Passwords are set when you extract the database, but can be changed using this command:&lt;br /&gt;
&lt;pre&gt;grant connect to &amp;lt;username&gt; identified by &amp;lt;password&gt;
&lt;/pre&gt;
If you change your own password, don't forget to set SIEBEL's password to the same; otherwise you might forget it.  You'll have to log in as SIEBEL to change SIEBEL's password.  SIEBEL can also change your password, so you might as well log in as him.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-3792974877944391438?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/3792974877944391438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/working-with-local-database.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/3792974877944391438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/3792974877944391438'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/02/working-with-local-database.html' title='Working with the Local Database'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-833450457622807111.post-6119653348680548974</id><published>2009-01-30T16:13:00.001-08:00</published><updated>2009-04-24T09:57:11.866-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server Script'/><title type='text'>Getting the Call Stack from eScript</title><content type='html'>I've been working on some routines for exception logging; basically recording some important data when an exception condition occurs. Right now it records things like the error code, error message, application name, active view name, user id, primary position id, organization id, server name, and a bunch of other stuff. You get the idea.&lt;br /&gt;
&lt;br /&gt;
Well today, I decided to add a call stack for those times the exception occurs in server script.&lt;br /&gt;
&lt;br /&gt;
Where did I get the call stack from? I noticed that the call stack is displayed when an exception is thrown and we push it to the screen using TheApplication().RaiseErrorText(e), where e is the exception object. So I knew the call stack was available somewhere in that exception object.&lt;br /&gt;
&lt;br /&gt;
Let's hack the exception object and see what it contains. A quick run of this code in the business service simulator was very revealing:&lt;br /&gt;
&lt;pre class="jscript" name="code"&gt;try
{
  TheApplication ().RaiseErrorText ("Hello, World!");
}
catch (e)
{
  for (var key in e)
    Outputs.SetProperty (key, e[key]);
}&lt;/pre&gt;
Here are the values that came out:&lt;br /&gt;
&lt;table border="1"&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Property&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Value&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;errText&lt;/td&gt;&lt;td&gt;Hello, World!&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;errCode&lt;/td&gt;&lt;td&gt;22709&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;name&lt;/td&gt;&lt;td&gt;Error&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td valign="top"&gt;message&lt;/td&gt;&lt;td&gt;
SiebelError: Hello, World!***RAISE ERROR TEXT***

Error near no filename:159 [RaiseErrorText()].

from no filename:159 [Service_PreInvokeMethod()]
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;
So I can see that the message property of the exception object houses the message I threw along with the call stack (at least when I threw that exception using RaiseErrorText()). So I can use that to my advantage.&lt;br /&gt;
&lt;br /&gt;
Actually, the construct was something like this:&lt;br /&gt;
&lt;pre style="FONT-SIZE: 12px"&gt;"SiebelError:" + &amp;lt;error message&amp;gt; + "***RAISE ERROR TEXT***" + &amp;lt;call stack&amp;gt;
&lt;/pre&gt;
I didn't really have a need for anything before the call stack, so I stripped out everything up to and including the ***RAISE ERROR TEXT*** bit. So finally, here's the function I wrote to get the call stack.&lt;br /&gt;
&lt;pre class="jscript" name="code"&gt;function GetCallStack ()
{
  try
  {
    TheApplication ().RaiseErrorText ("");
  }
  catch (e)
  {
    return (e.message.replace (/^.*\*{3}RAISE ERROR TEXT\*{3}/, "");
  }
}&lt;/pre&gt;
If that return line looks Chinese to you it's because I am part Chinese. Allow me to translate...&lt;br /&gt;
&lt;br /&gt;
I stripped out the junk prefix by using the string.replace() method to replace unwanted text with an empty string. The unwanted text was expressed as a regular expression, which basically reads, "Everything from the beginning of the line until ***RAISE ERROR TEXT***" So pretty straightforward logically.&lt;br /&gt;
&lt;br /&gt;
Well there you have it! I'll save the primer on regular expressions for another day.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/833450457622807111-6119653348680548974?l=siebelhacker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://siebelhacker.blogspot.com/feeds/6119653348680548974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://siebelhacker.blogspot.com/2009/01/getting-call-stack-from-escript.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/6119653348680548974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/833450457622807111/posts/default/6119653348680548974'/><link rel='alternate' type='text/html' href='http://siebelhacker.blogspot.com/2009/01/getting-call-stack-from-escript.html' title='Getting the Call Stack from eScript'/><author><name>Mike M. Lin</name><uri>http://www.blogger.com/profile/15777749776576992680</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_ZqD0HGgm6Ps/TEfuuwbTLVI/AAAAAAAAA-A/Yr5zp3oXuGM/S220/Caden+Loves+Grandpa.jpg'/></author><thr:total>1</thr:total></entry></feed>
