Software Engineer
-
Write a resume that will land you a programming job
By Justin James | October 8, 2007, 10:10 PM PDT
Justin James lays out what he sees on a developer's resume that makes him say "wow!"... and what makes him say "ugh!"
-
Create rich interfaces with Microsoft Silverlight
By Tony Patton | October 8, 2007, 7:14 PM PDT
Microsoft's Silverlight is a cross-browser, cross-platform plug-in for delivering the next generation of media experiences and rich interactive applications for the Web. Find out why Tony Patton is impressed with the Silverlight development model.
-
Creating a Web service with VB.NET
By Irina Medvinskaya | October 4, 2007, 12:05 PM PDT
VB.NET allows you to use Web services as if they were entirely local objects since most of the marshaling between the client and the server is taking place in the background. This tip shows you how to create a simple Web service.
-
Multithreading is a verb not a noun
By Justin James | October 1, 2007, 8:33 PM PDT
Steve Yegge's rather famous post, "Execution in the Kingdom of Nouns" has probably done more to frame and influence my thoughts about object-oriented programming (OOP) than anything else out there. In the discussion thread about my post on multithreading loops, I finally got a handle on why I feel that multithreaded work is significantly more difficult than it needs to be: the noun-oriented nature of the languages that I have written multithreaded code in. Of course, it is entirely possible for there to be an OO language without the focus on nouns (Chad Perrin says that Ruby is one of them, but I have not worked in it). But, at the end of the day, the noun-ness of mainstream OO languages makes multithreading no better than miserable to work in. A great example of what I am talking about is the code in my VB.Net multithreading series. Look at the code for working with a monitor. This simple example is fairly hard to follow to be honest. By glancing at the code, even someone who knows VB.Net and multithreading fairly well like myself cannot quickly judge what is going on. Why is this? Because multithreading is an extreme example of what Steve Yegge's article is about. Multithreading is purely verb oriented, and the objects involved do not need to be. The programmer does not need to be passing about a mutex object, for example. Mutex's are active across the entire system, so why even bother to pass them around? Why not have a "lock" command and pass it parameters like scope (which would determine whether it used a mutex or a monitor) and the name of the lock, and have the run time environment manage a hashtable of various locking objects? Let's ditch these semaphore objects and have the language have a "listen for signal" command and a "send a signal" command. Would this be too difficult? I truly doubt it! The fork() command on UNIX has been around forever. Regardless of your language, using a process fork on the UNIX platform feels the same because it is a base feature of the OS, and various C-style languages all expose that functionality fairly identically if they expose it. Furthermore, System V IPC is already a standardized, verb-based system. There is already one example of this: SyncLock (that's VB.Net parlance, it is simply "lock" in C#). SyncLock does a cheap monitor lock against an object that you provide. Sadly, extending VB.Net or C# at the level of creating a new block construct is either very tough or impossible to the best of my knowledge. If it was possible, it would be fairly easy to write a DSL (like LINQ is) to perform multithreading, and then use that DSL within VB.Net, C#, etc. to easily handle the multithreading work without having to explicitly and overtly deal with the .Net Framework's ugly, noun-oriented multithreading systems. Indeed, SyncLock "feels" really out of place; I cannot think of any other language-level statements in VB.Net that accept any type as a parameter and actually work -- even the built-in casting calls like CInt and CStr are limited to certain types; calling CInt on a Bitmap object is a compiler error, not a runtime error. The problem is that the "Kingdom of Nouns" values conformity over utility. There are some very good reasons for it. If I can demand an exception for multithreading work, then someone else (just kidding, it would be me again) would demand that regex's be run as an operator the way that Perl does. And then someone else would want their domain-specific functionality to be bumped up to function or operator status. And the next thing you know, we turned C#, Java, or VB.Net into K&R C with a huge set of libraries pre-included. Yuck. I think maybe what would be better (and this is why I love the .Net CLR) would be to have something similar to LINQ but for multithreading, and write it in a language much better suited for this work. Then, access this DSL in the same consistent way regardless of what language your project is actually in, much as everyone uses the Perl regex syntax now. LINQ is based on closures; doing something similar could very well be the ticket to making the .Net ecosphere a multithreading paradise. (MSDN has a great in-depth article on how LINQ works.) Interestingly enough, it looks like Microsoft Research is already headed down this path. Let's do the math here. F# gets more and more mentions from internal Microsoft people. Closures are getting added to VB 9 (in .Net 3.5) because LINQ requires them. LINQ and a rather SQL-like (and therefore, imperative feeling) structure gets added across the .Net board, replacing and improving on a wide scale the concept of "query," and with it, much of the existing ADO.Net structure. Microsoft has been throwing a good deal of effort behind IronRuby and IronPython. Team Foundation Server, plus the associated tools, can do much of the organizational stuff that OO helps with, in terms of multiple programmers working on the same codebase. Microsoft Research is adding "design by contract" to C# with Spec#, a superset of C#. Add this all up, and it says to me that Microsoft is starting to push very hard against strict OO. Hopefully, Microsoft Research's TPL will do for multithreading what LINQ is doing to the concept of queries. J.Ja
-
Sending blob attachments in e-mail with utl_smtp
By Rex Baldazo | September 30, 2007, 5:48 PM PDT
Last time, I showed how to send an HTML-formatted e-mail from an Oracle PL/SQL application using utl_smtp. I promised I would extend the package a little with a second method that allows you to send Binary Large OBject (blob) attachments in the e-mails. The most common application where I work is sending PDFs that are stored in the database to various recipients.
First, you have to add the method into the package spec so that other packages can use it:
procedure send_blob ( p_sender varchar2, p_recipient varchar2, p_subject varchar2, p_filename varchar2, p_blob blob);Here is the actual method you need to insert into the package body:
procedure send_blob ( p_sender varchar2, p_recipient varchar2, p_subject varchar2, p_filename varchar2, p_blob blob) is c utl_smtp.connection; v_raw raw(57); v_length integer := 0; v_buffer_size integer := 57; v_offset integer := 1; begin common(p_sender, p_recipient, p_subject, c); utl_smtp.write_data( c, 'Content-Disposition: attachment; filename="' || p_filename || '"' || utl_tcp.crlf); utl_smtp.write_data( c, 'Content-Transfer-Encoding: base64' || utl_tcp.crlf ); utl_smtp.write_data( c, utl_tcp.crlf ); v_length := dbms_lob.getlength(p_blob); <<while_loop>> while v_offset < v_length loop dbms_lob.read( p_blob, v_buffer_size, v_offset, v_raw ); utl_smtp.write_raw_data( c, utl_encode.base64_encode(v_raw) ); utl_smtp.write_data( c, utl_tcp.crlf ); v_offset := v_offset + v_buffer_size; end loop while_loop; utl_smtp.write_data( c, utl_tcp.crlf ); utl_smtp.close_data( c ); utl_smtp.quit( c ); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit( c ); raise; when others then raise; end send_blob;Notes about the code
You have to pass a filename along with the actual blob. You also need to make sure it has the right extension so that the e-mail client on the other end will be able to open it up properly. That is, if the blob is a PDF, then send a filename like
abc.pdf.You'll notice that this method doesn't send a body. I'm trying to keep it simple to focus on the actual sending of the blob. If your application requires it, you should be able to incorporate code from the other method to include an e-mail body as well.
The weird while loop in the method
<<while_loop>> while v_offset < v_length loop dbms_lob.read( p_blob, v_buffer_size, v_offset, v_raw ); utl_smtp.write_raw_data( c, utl_encode.base64_encode(v_raw) ); utl_smtp.write_data( c, utl_tcp.crlf ); v_offset := v_offset + v_buffer_size; end loop while_loop;The buffer size must be 57 for utl_encode to work, which is why we loop thru the blob and chunk it into 57-byte pieces. This process converts the blob into a raw binary format and then sends the 57 bytes into the e-mail stream. It also adds an end-of-line after each 57-byte chunk.
Once you have the basics figured out in utl_smtp, it's not a huge deal to include attachments.
-
Adding a Setup Wizard to VB.NET applications
By Irina Medvinskaya | September 27, 2007, 12:12 PM PDT
Visual Studio .NET simplifies the process of installing your applications by providing an easy way to add the Setup Wizard to your applications. In this tip, Irina Medvinskaya will create a simple VB.NET Windows application and add the Setup Wizard to it in order to allow the Windows application to install.
-
Sending e-mail from an Oracle database with utl_smtp
By Rex Baldazo | September 26, 2007, 4:51 PM PDT
If you're running Oracle 10g or later, you can use the nice modern utl_mail package to send e-mails from your PL/SQL applications. Even though the application I maintain is now running on Oracle 10g, it was built back on an Oracle 8i database, so it sends e-mails via the older (and more complicated) utl_smtp package. The nice thing about this code is that it runs fine on Oracle 10g, so we haven't had any need to replace utl_smtp with utl_mail. I'm sure that day will come eventually, but for now, utl_smtp serves our needs. To begin, the utl_smtp package has to be installed (in the SYS schema, naturally). If it wasn't part of your install, you can find the utlsmtp.sql script in your ORACLE_HOME\RDBMS\admin directory. You'll also need utl_tcp; again, if it's not already loaded, the utltcp.sql script for that is in the same location as the utlsmtp.sql. Finally, you will need to know the URL for your corporate SMTP server. (Note: This example won't work with secured SMTP servers like Gmail.) The spec for our little e-mail package is fairly straightforward:
create or replace PACKAGE sendmail IS procedure send (p_sender varchar2, p_recipient varchar2, p_subject varchar2, p_body varchar2 default null); end sendmail;For the body, you'll notice that the public methodsendrelies on a private method calledcommonbecause I want to extend this package later and show how to send Binary Large OBject (blob) attachments. For example, if you've generated a PDF and stored it in your database, you might want to e-mail it as an attachment; thecommonmethod is in preparation for that. The code that will be used is from the basic send method and the send_blob method. Here's the package body:create or replace PACKAGE BODY sendmail IS procedure common (p_sender varchar2, p_recipient varchar2, p_subject varchar2, c out utl_smtp.connection) is v_recipient varchar2(1000); begin --make connection to smtp c := utl_smtp.open_connection('smtp.example.com'); --identify the domain of the sender utl_smtp.helo(c, 'example.com'); --start a mail, specify the sender utl_smtp.mail(c, p_sender); --identify recipient utl_smtp.rcpt(c, v_recipient); --start the mail body utl_smtp.open_data(c); utl_smtp.write_data(c, 'From: ' || p_sender || utl_tcp.crlf); utl_smtp.write_data(c, 'To: ' || p_recipient || utl_tcp.crlf); utl_smtp.write_data(c, 'Subject: ' || p_subject || utl_tcp.crlf); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(c); raise; when others then raise; end common; procedure send (p_sender varchar2, p_recipient varchar2, p_subject varchar2, p_body varchar2 default null) is c utl_smtp.connection; begin common(p_sender, p_recipient, p_subject, c); utl_smtp.write_data(c, 'Content-Type: text/html' || utl_tcp.crlf); utl_smtp.write_data(c, utl_tcp.crlf || p_body); utl_smtp.close_data(c); utl_smtp.quit(c); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(c); raise; when others then raise; end send; end sendmail;There are a couple of places above where you'll need to substitute your specific information. First is the line where I provide the SMTP server:--make connection to smtp c := utl_smtp.open_connection('smtp.example.com');That's where you'll want to put whatever your corporate SMTP server happens to be. And the second place is where you identify your domain:--identify the domain of the sender utl_smtp.helo(c, 'example.com');Again, replace that with whatever your domain really is. That's all you'll need to get the basic e-mail functionality working. To call this, you'd use something like:begin sendmail.send ('sender@example.com', 'recipient@example.com', 'Subject: Testing', 'Howdy!'); end;You'll notice that the body string I gave above has HTML embedded in it. This is because, in thesendmethod, I set the content type to be text/html:utl_smtp.write_data(c, 'Content-Type: text/html' || utl_tcp.crlf);
Don't be like my coworker who spent hours trying to send out formatted e-mails with chr(10) embedded as the linebreak character. It won't work -- HTML ignores that. You'll need to use break or paragraph tags to format the message body. Next time, we'll send blobs as attachments. -
Working with .NET access modifiers
By Tony Patton | September 25, 2007, 9:58 AM PDT
The access modifiers available in .NET allow you to put encapsulation in action by defining who can use classes, methods, properties, and so forth, as well as keeping out those who don't need them. Here is a rundown of the various access modifiers available with the .NET Framework.
-
How important is multithreading in application development?
By Justin James | September 24, 2007, 9:55 PM PDT
I think multithreading in application development is the wave of the future -- even though not all applications lend themselves to being multithreaded.
In a blog post on MSDN about symmetric multicore processing being a 'dead end,' the author makes a lot of excellent points, not the least of which is that all too many applications still need one big core to work effectively. However, the author fails to see where the CPU market is headed and that the days of Moore's Law applying to individual cores is over for the time being.
I have been working on a very nifty little application for an article I am writing that will take me about a month's worth of weekends. The application does some image editing, but the editing it performs is rather CPU intensive. The CPU crunch shows a rather intriguing pattern.
As you can see in this Task Manager screenshot (Figure 1), one of my cores (this is a Core 2 Duo system) is cranking pretty hard. The other core is spinning but not so hard. The difference between the two is that the hard working core (the one on the right) is running my application. The "lazy" core is me doing the rest of my work on the PC, as well as Visual Studio handling the overhead of my application running within it (I am still debugging). For example, the two big spikes on the "lazy core" are two times where UAC kicked in (I was moving items on the Program menu).

Figure 1 (Click image for full size)
What can I do? My first option is to leave the situation as it currently stands. Sure, the application is taking 10+ hours to run through a relatively lightweight operation, but it is rock solid on reliability, and the RAM usage is insanely stable, which reduces a ton of page file hits. My next choice is to try multithreading some portion of the work. As you can see, I have one core working hard, but one of them is not doing a thing to help me -- there is a lot of untapped power in my hardware. The system is still extremely responsive, and I am not seeing any slowdown. Looking at the graph (and the process list), my application is hovering around 48% or so of CPU, which is nearly 100% of the core that it is on. Popping off a second thread would make the system really slow (since I would be taking 100% on both cores), but it may allow me to finish the task in half the time. That is a tough trade off to consider.
I think there is a middle road in this case. Looking at the workload, there is no one particular portion of the workflow that could be performed asynchronously. Even if there was, none of the operations are long enough for the cost of context switching to be offset. Now that being said, the overall operations are performed in near total isolation of one another, and while they work with a common point of memory, that access is fairly quick and is only a small portion of the functionality. In other words, it is a low contention area. So having identified only one potential contention area (and being a rare case of a block occurring), we have found our middle road.
I am going to try to split up the loop, following my general rule on the number of threads: single thread CPU usage * number of logical cores. So, if it takes 50% of one logical core to run the processing thread, you do not want more than four threads running on a system with two logical cores; this puts your workload at 100% of all cores. I often decrement that number by 1 to ensure that the base OS and other applications are not completely squeezed. After all, does your customer care that your application is as efficient as possible if it effectively renders his/her PC useless while it is running? Probably not.
In this case, however, I am going to try something different. I will usually split the loop evenly and have each loop do its work in perfect parallel. This time, I am going to have one thread marked as a special "stutter thread" (I am making up words here -- I am not sure if there is a proper term for this). The work will not be evenly divided; the "stutter thread" will have only half of its "fair share" of work to do, and the other threads will have the other half evenly divided amongst themselves. In exchange for having less work to do, the "stutter thread" will only "work" 50% of the time. The other 50% of the time, it will remain idle, freeing up a touch more CPU for the OS and other applications. I will most likely use a semaphore tied to another thread (say, thread 0 signals the "stutter thread" on every other iteration). I could also use a monitor (thread 0 enters the monitor on every other iteration, and the "stutter thread" also tries entering the monitor). I think either approach would be viable.
I will let you know in a few weeks how this goes. (I am going out of town this weekend, so I will not be working on it.)
J.Ja
-
Ensure your Web site displays properly with character encoding
By Tony Patton | September 24, 2007, 7:50 PM PDT
Tony Patton examines why developers use character encoding for Web pages, outlines the options you have, and offers guidance on how to choose a character encoding.
-
Do comments slow down PL/SQL?
By Rex Baldazo | September 22, 2007, 5:58 PM PDT
I'm not sure where this started, but at work there's this rumor going around that if you put too many comments in an Oracle PL/SQL package, it impacts performance. That is, the more comments in your code the slower it runs. I could kind of understand if the language was interpreted because the comments would have to be read in by the interpreter and thus could have an impact on performance. But PL/SQL gets compiled in the database, so I did not see how comments could be a problem. There's only one way to really tell, of course, and that's to run experiments. So, doing my best MythBusters imitation, I decided to take a crack at it. I started by creating a table called TABLE1 (sorry, I was lazy and just used the table name that SQLDeveloper gave me). The table had three fields: a varchar to store the name of the method and two timestamp fields for the start and end times. The DDL looked something like this:
create table TABLE1 ( methodname VARCHAR2(255 BYTE), starttime TIMESTAMP (6), endtime TIMESTAMP (6) )Then I created a package with two methods. The basic code in both methods was identical. Here's the code from the version without comments:procedure comments_n AS counter integer := 0; starttime timestamp; BEGIN starttime := current_timestamp; while counter < 9999999 loop counter := counter + 1; end loop; insert into Table1(methodname, starttime, endtime) values ('comments_n', starttime, current_timestamp); commit; END comments_n;The second method, called comments_y, was identical, except I liberally sprinkled single-line and multi-line comments everywhere. And, yes, I put comments inside the loop since that's where most of the time will be spent in this method. I then called the methods with a little anonymous block, like this:begin pkg_timingtest.comments_n; pkg_timingtest.comments_y; end;
The first five times through I called the procedure without comments first; then I edited this anonymous block so that the procedure with comments got called first. IÂ re-ran it another five times. When that was done, I averaged up the time differences and grouped them by the method name:select methodname, avg ((extract(second from (endtime - starttime))) * 1000) as diff from table1 group by methodname;
I repeated this experiment several times. On some runs, the method with comments would average faster times than the one without. In those cases where the method with comments was slower on average, it was by just two or three milliseconds, which is not a significant percentage when the average runtime was over 2,400 milliseconds. I consider this myth busted. -
Enhance applications with the ASP.NET AJAX Control Toolkit
By Tony Patton | September 18, 2007, 12:15 PM PDT
The ASP.NET AJAX Control Toolkit provides an overwhelming number of options to spice up the UI, while taking advantage of AJAX programming techniques that already have a positive influence on the UI.
-
A dirge for CPAN
By Justin James | September 17, 2007, 7:59 PM PDT
On my way out the door tonight, I stopped to briefly speak with a coworker. I noticed that he was perusing CPAN. For those who are not familiar with it, CPAN is the Comprehensive Perl Archive Network, the collection of Perl libraries. As far as I know, no one has even bothered to
make something similar to it for Perltry to compete with it in the Perl world. [Edited 9/18/2007 {Justin James} for clarity] I was surprised my worker was on CPAN for two reasons. First of all, this person really does not like Perl. Second of all, his project is in VB.Net. So why in the world would he be looking at CPAN? Because if you need to write it, there is a darn good chance someone already wrote it in Perl and put it on CPAN. Apparently, this coworker uses CPAN the way most coders use Google -- as a source for example code. CPAN is a positively amazing resource for the following reasons:- CPAN code tends to be of high quality (although it's quite often of dubious usefulness).
- CPAN is beyond comprehensive. As of 9/17/2007: 12,168 modules encompassing a whopping 3,898 MB of code.
- CPAN is a universal resource; everyone who has written enough Perl to put it on a server somewhere will put it on CPAN because everyone else puts their code on CPAN.
- CPAN is simple to use. Not only is the Web site so low tech you cannot get lost on it, but the Perl package itself comes with simple tools to access CPAN.
- CPAN bundles are easy to use and access, regardless of whether you download them, view them on the screen and save the text, or use the Perl CPAN tools.
- CPAN code is self-documenting in the Perl POD format. Say what you will about POD (it has some warts), but it is a good format for libraries since it is built into the library and source code at the same time.
- Perl is an interpreted language so, by their nature, any libraries and modules are open source, editable, and viewable.
- The licensing terms are quite gentle; while each module in CPAN has its own license agreement, I cannot recall ever seeing one that did not seem to say, "do what you want, I don't care."
What did CPAN accomplish that no one else did?
I have no answer to that question. I know that of all of the systems out there, CPAN feels the least professional. The site is probably running on 10-year-old CGI code. The site itself has not been updated in more than five years with the exception of the contents. As far as I can tell, there is no corporate sponsorship of any kind. It does not support "workspaces" or "projects" in any way. There is not a drop of advertising on it other than a tiny logo and a link to the company doing the hosting. In a nutshell, it is like an FTP site with a rudimentary search engine on top of it. At the end of the day, CPAN is something that simply "just happened" without any conscious thought or decision. The more that big sponsors try to replicate CPAN or (even worse) to foster "community," the more they seem to fail. CPAN is probably one of the top five reasons I miss working in Perl on a regular basis; the lack of an equivalent is one reason why I will never quite adjust to the .Net ecosystem or take a shine to it the way I did Perl. I could spend hours going through CPAN, finding obscure pieces of code (Klingon language parsers, anyone?), reading through them, and learning a lot. Most of the open source stuff out there comprises an entire project, and it is both too large to make much sense from and too broad in scope to learn specific ideas from. For instance, you might need to go through thousands of lines of code that deal with the interface and validation just to find the 100 lines of interesting logic in any given project. I know... at this point I am Ted, and Perl is Mary; it's years later, and I am still hung up on her. But, in this case, I think there is something really special about the past that no artificial attempts to recreate will ever bring back. J.Ja -
Develop JavaScript with the JSEclipse plug-in
By Tony Patton | September 17, 2007, 1:46 PM PDT
JavaScript developers have been clamoring for development tools for years. Tools like Firebug and Venkman answer the call, but there are more options available. Adobe Labs offers another option with the JSEclipse add-on for the Eclipse development platform. It provides a full-featured development environment for working with JavaScript. Here's an examination of JSEclipse, as well as the Eclipse platform.
Eclipse
In 1998, IBM began creating a development tools platform that eventually became known as Eclipse. The goal was the creation of a common platform for development products to avoid duplicating the most common elements of infrastructure. The first product release included a Java IDE, as well as the broader platform to go with it. In 2001, it was made open source with the creation of the Eclipse consortium. It has evolved into the industry's major non-Microsoft software tool platform. It is a powerful tool for building Web and Java applications. It was built using Java, so that is its one main requirement. An added benefit is its availability on most operating systems.JSEclipse
JSEclipse has been around for quite some time; it was originally developed by a company called Interakt, which was acquired by Adobe. Its support and development is now handled by Adobe Labs. JSEclipse is an add-on for the Eclipse platform; it requires an Eclipse installation. It is installed via the software updates area of Eclipse. It is available as a free download once you register with the site. Once it has been installed, a JSEclipse menu is available within the Eclipse IDE when working with source code. The focus of the JSEclipse tool is the creating and editing of JavaScript code. It includes the following features:- Code completion: The plug-in adds JavaScript contextual code completion and shortcuts within the Eclipse IDE. This is a great feature given the fact that no developer can memorize every property and method and all JavaScript objects.
- Outline and navigation: JavaScript code and function declarations are easily traversed with project outlines.
- Syntax highlighting: This feature provides a color coding scheme for various elements in JavaScript like comments, keywords, constants, and strings. You can also define custom color schemes.
- Error reporting: You can easily locate code errors with the error reporting features of JSEclipse.
- Templates: You can create and customize code templates to provide a starting point for current and future projects.
- Library support: JSEclipse supports popular JavaScript libraries such as Dojo, Prototype, Spry, and YUI, so you can integrate them in your project and easily access and use their features.
- Documentation: The JavaDoc documentation syntax is supported within your code comments.
- Product support: Given that it is an Adobe product, JSEclipse is fully compatible with the Adobe Flex Builder 2 offering.
Impressions
As a longtime developer with such tools as NetBeans, Visual Studio, and Eclipse for Java development, I prefer the look and feel of a full-featured development environment that lets me easily work with project-oriented development. Also, a robust IDE provides context-sensitive help, as well as a full help system when your memory fails to recall the name of an object or its properties. The separate section at the bottom of the Eclipse interface provides real-time feedback on code problems, including the line number and an intuitive description of the project. The installation of both Eclipse and JSEclipse are simple and straightforward. Downloads are available for most operating systems, which is another great feature since you are not restricted to the Windows platform. The EasyEclipse offering provides a good starting point for first-time users; it includes a variety of plug-ins to help you get up and running. A drawback of the JSEclipse plug-in is the separation from the rest of a project I may be developing, as I work with .NET-based solutions and other Web technologies. I can take advantage of other plug-ins to use Eclipse for everything. One of the great features of the Eclipse platform is its extensibility via its plug-in support. In addition to JSEclipse, there is a variety of plug-ins available to accommodate most development languages and tasks. The following list provides a sampling of what is available:- Amateras Html Editor: While the current version of Eclipse provides XML support, this tool adds CSS and HTML, along with XML support to the IDE.
- ASDT: Allows ActionScript developers to use Eclipse for the development projects.
- EPIC: Brings Perl support to Eclipse.
- PHPEclipse: Lets you develop PHP code within Eclipse.
- Subclipse: Version control system for use with Eclipse.
Conclusion
The JSEclipse plug-in is a viable option for JavaScript developers who are familiar with Eclipse or have a desire to use the Eclipse platform. JSEclipse provides an environment for developing and debugging custom JavaScript code that may take advantage of freely available libraries. The context-sensitive and online help are two of the best features because you have everything you need at your fingertips (i.e., no running to the bookshelf or performing Google searches). If you are content with your current Web development tools, then diving into a whole new environment with Eclipse may not be best for you. Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge. --------------------------------------------------------------------------------------- Get weekly development tips in your inbox Keep your developer skills sharp by signing up for TechRepublic's free Web Development Zone newsletter, delivered each Tuesday. Automatically subscribe today! -
ORA-04030 doesn't always mean you're running out of RAM
By Rex Baldazo | September 16, 2007, 2:10 PM PDT
I maintain an ancient Oracle Reports system, which does a peculiar FTP gyration that recently started giving us errors. Here's the scenario: We have a database that powers a farm of six Oracle Reports servers. Some of the reports we generate are tilde-delimited text files that have to be FTP'd into a mainframe computer. (Don't ask -- it's an ancient system and it's not going to be changed anytime soon.) This was all written before the feature was introduced in the Oracle Reports server that supports FTP as a target. In other words, it was written before we could FTP directly from the Reports server into the mainframe. So when the database sends a URL to one of the Reports servers, it waits and reads back in the resulting report text file. This gets saved as a blob in the database, and the database periodically exports the blobs into the local file system and runs an external Java FTP process to push those files into the right location on the mainframe. Things started blowing up recently when the 10g server tried to save the incoming text file as a blob in the database. There's no way -- at least no way that I know -- to stream the incoming file into the database. It has to wait, read in the entire text file from the Reports server, and then save that entire chunk into the database, which means that the database has to allocate temporary storage somewhere to hold the text file until it can be written out. These text files are not small -- some of them have grown into the hundred-megabyte range. These six files are scheduled very early in the morning, so there should not be that much traffic on the database server I'm using; besides, the database server has 8 GB of RAM and only runs the database. There is plenty of capacity to temporarily hold these reports. We recently started seeing a bunch of ORA-04030 errors in our application error log. The error text would say something like "out of process memory when trying to allocate 16396 bytes." Our first thought was to check RAM usage, which we did, and everything looked fine. The database had way more headroom than it needed to allocate RAM for these files. Our DBA opened up a support ticket with Oracle and, after a bit if investigating, it turns out we were running low on swap space for the database. We had a couple GB of free disk space but apparently that wasn't enough for the hungry database server. Luckily, it's not a real disk -- it's virtual running on a big EMC disk farm. We were able to fairly easily get it expanded to give more room for the database. I'm still not clear on why the database didn't warn us specifically about the swap space issue. Why give this general out-of-memory error, which mislead us into thinking RAM was the issue? If the database knew it was swap space at issue instead of RAM, it should have been indicated in the error text.
-
Using the PrintDocument component in VB.NET applications
By Irina Medvinskaya | September 13, 2007, 9:20 AM PDT
If you want to allow users to print form components in run-time, the PrintDocument component lets you offer users this functionality. The PrintDocument component is an object that allows users to send an output to a printer from Windows Forms applications. In this tip, I show you how to use the component in your VB.NET applications.
Using PrintDocument
In order to use the PrintDocument component, you need to double-click on the PrintDocument component in the Toolbox. Once the component is added to the form, you can set its properties and print. In my example, I will add the PrintDocument component, a TextBox, and a command button to the form. Then, I will add the following code:Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click        PrintDocument1.PrinterSettings.Copies = 2        PrintDocument1.Print() End Sub Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage        e.Graphics.DrawString(TextBox1.Text, TextBox1.Font, Brushes.Blue, 100, 100) End Sub
How this works
When debugging the application, click on the command button. The text found in the TextBox (usually TextBox1, assuming that you didn't change it), will print to the default printer. When the button is clicked, two copies of the document will be sent to the printer since we requested two copies by setting the Copies property value to 2. On the Print_Page event of the PrintDocument, I use the Graphics class' DrawString method to select the object contents of a TextBox, specifying the font, brush color, and the sizes. Irina Medvinskaya has been involved in technology since 1996. She has an MBA from Pace University and works as a project manager at Citigroup. ---------------------------------------------------------------------------------------- Get Visual Basic tips in your inbox Advance your scripting skills to the next level with TechRepublic's free Visual Basic newsletter, delivered each Friday. Automatically subscribe today! -
Implement ASP.NET AJAX with the UpdatePanel control
By Tony Patton | September 11, 2007, 10:30 AM PDT
The initial momentum of the AJAX revolution has yet to diminish, as developers continue to embrace the technology and develop more user-friendly applications. The availability of ASP.NET 2.0 AJAX Extensions 1.0 brings AJAX development to the ASP.NET developer using familiar programming techniques. The UpdatePanel control offers so many options to easily incorporate AJAX functionality -- most notably, partial-page updates -- with ease.
-
Monitor Web site requests with Mozilla's LiveHTTPHeaders extension
By Tony Patton | September 11, 2007, 12:15 AM PDT
The LiveHTTPHeaders Mozilla extension is a useful tool for both Web developers and administrators. It provides an easy way to monitor HTTP activity and track down potential problems with Web requests. Learn more about the LiveHTTPHeaders extension, and get a quick HTTP primer.
-
Is SLOC a valid measure of quality or efficiency?
By Justin James | September 10, 2007, 9:56 PM PDT
Yesterday I sat down to start work on a small project. Now, when I say small, it generally means less than 2,000 source lines of code (SLOC). For some people, that is huge -- for other people, that is barely on the radar. I find it interesting that, since I shifted from being primarily a Perl developer to being primarily a VB.Net developer, my perception of a small project has dramatically changed. When I was working in Perl, 200 SLOC was a small project. My experience has been that it takes between 500 and 1,000 SLOC of VB.Net to approximate 200 SLOC of Perl in terms of overall functionality. The standard response to this (and the usual takeaway) is, "Perl is more efficient than VB.Net in terms of SLOC." I generally agree with that statement, and there is research out there that proves it. Here's the real question: Is SLOC the best measure of a piece of code?
Analyzing language syntaxÂ
Let us look at an example to see which of these two code snippets is really better. Code 1Dim Obj as MemoryHog = New MemoryHog Dim Val as String Obj.FillWithTonsOfData Val = Obj.Property Console.Writeline("Val is: " & Val) Console.Writeline("Val + 1 is: " & Val + 1) Console.Writeline("Val * 1000 is: " & Val * 1000)Code 2Dim Obj as MemoryHog = New MemoryHog Obj.FillWithTonsOfData Console.Writeline("Val is: " & Obj.Property & VbNewLine & "Val + 1 is: " & Obj.Property + 1 & VbNewLine & "Val * 1000 is: " & Obj.Property * 1000)By the SLOC measure, Code 2 is significantly "better" than Code 1. But when you take a closer look under the hood, Code 1 has a number of advantages over Code 2. While it does take a bit more memory than Code 1 because of the extra variable Val, it is more efficient on the CPU, as it does not have to keep dereferencing Obj.Property. This is a common refactoring. Also consider that, while the latter portion of Code 1 is probably slightly less efficient on the CPU than the final, equivalent line in Code 2 because it has fewer function calls, it is simultaneously less efficient due to all of the concatenation in it. In fact, it has enough concatenations to make using the StringBuilder class a viable option. Additionally, it is a much more difficult (although still not "difficult") line of code to understand than the equivalent three lines from Code 1. As you can see, SLOC "efficiency" is hardly applicable, even within the same language.Clever code
There is also the issue of the "cleverness" of code. I will be honest -- I adore elegant code. An example is some of the tricks with UNIX pipes. I've also always liked the C convention where "true" means "not zero," which can save a ton of typing (compare the C-esque if (String.Length) to the VB.Net'y If Not String = String.Empty or If Not String = "" or If String.Length > 0). The efficient language folks have an argument that goes like this:- Each line of code is a potential point of failure.
- Each line of code takes time to plan, type, review, and debug.
- Fewer lines of code reduce failures and increase coding speed.
- Clever code takes longer to plan, review, and debug than verbose code.
- Programmers who can work well with clever code and who can write clever code well are much rarer and expensive to hire (and probably harder to retain) than more verbose programmers.
- Clever code can have more points of failure per line of code.
- The real points of failure are variables, operators, and statements that make up a SLOC -- reducing those is what truly reduces points of failure. One SLOC with the same number of operations and variables as 10 lines of code has just as many potential points of failure.
Becoming a more efficient programmer
At the end of the day, whether code is clever and reduces SLOC is fairly irrelevant in my book. Refactor the code to increase readability, reduce variable, statement, and operator count wherever possible and reasonable, and you are well on your way to becoming a higher quality, more efficient programmer. J.Ja -
Split data onscreen logically with VB.NET's Tab Control
By Irina Medvinskaya | September 6, 2007, 1:31 PM PDT
VB.NET developers are often tasked with having to display a lot of necessary information on the screen with limited space. If you can split the data on the screen logically into different sections, you should consider using the Tab Control. In this tip, I will show you how to use the Tab Control to allow data to be logically split on the screen.
How to use the Tab Control
The Tab Control allows you to arrange data and other controls in a compact way. Users often like the Tab Control as well because screens with Tab Controls are fairly intuitive. In order to use the Tab Control in your applications, open the Toolbox and locate Tab Control under the Containers section. Drag the Tab Control onto the form and then start adding other controls to it. For instance, if you want to display the Tab Control with three tabs and a TextBox on each tab, you would create three tabs and then add a text box for each tab. Depending on the application's specifics, you may want to set some properties in the design time, but you will be able to set the same properties and even add controls to the Tab Control in runtime if necessary. The Tab Control is easy to use, and it provides a great deal of visual and styling flexibility. You can set the Tab Control's visual properties and apply styles to the individual parts of the control. Once you have the Tab Control on your form, the form will look like Figure A. Figure A
The Tab Control is initially displayed with two tabs; you can add tabs either using the properties of the control in design time or with the code in run time. In the code example below, I add a third tab to the Tab Control and a control to each tab in run time. To set the control properties in design time and add and/or modify tabs, click the Tab Pages collection, and you will see a screen that looks like Figure B.
Figure B
       Dim txt1 As New System.Windows.Forms.TextBox        Dim lbl1 As New System.Windows.Forms.Label        lbl1.Text = "abc"        Dim cbo1 As New System.Windows.Forms.ComboBox        With cbo1            cbo1.Items.Add("1")            cbo1.Items.Add("2")            cbo1.Items.Add("3")            cbo1.SelectedIndex = 0        End With        With TabControl1            .TabPages.Item(0).Text = "General Info"            .TabPages.Item(0).Name = .TabPages.Item(0).Text            .TabPages.Item(1).Text = "Details"            .TabPages.Item(1).Name = .TabPages.Item(1).Text            .TabPages.Add("Implementation")            .TabPages.Item(2).Name = .TabPages.Item(2).Text            .TabPages.Item(0).Controls.Add(txt1)            .TabPages.Item("Details").Controls.Add(lbl1)            .TabPages.Item(2).Controls.Add(cbo1)        End WithNotes about the example
I define three controls that I would add to different TabPages of the Tab Control: txt1 as a TextBox, lbl1 as a Label, and cbo1 as a ComboBox. I then set the Text property of the Label control (to make it visible in the example) and add a few items to the ComboBox control. The prep work is done, and I am ready to use the properties of the Tab Control to set the Text and Name properties of its two tab pages, and then add a third tab page. Finally, I add: the TextBox to the first tab, the Label to the second tab, and the ComboBox to the third tab. Since I assigned not only the Text but also the Name properties of each Tab Page, I was able to access them either by Item number as in Item(0) or by the Item name ("General Info"). Irina Medvinskaya has been involved in technology since 1996. She has an MBA from Pace University and works as a project manager at Citigroup. ---------------------------------------------------------------------------------------- Get Visual Basic tips in your inbox Advance your scripting skills to the next level with TechRepublic's free Visual Basic newsletter, delivered each Friday. Automatically subscribe today!