Friday, January 30, 2009

Quick Deploys And Assembly Resolution

The Error

We recently ran into the most bizarre error on a clients machine that hosts the central administration web site. Every 15 minutes on the dot we'd get the following error for many different assemblies. The error looked a lot like:

Event Type: Error
Event Source: Windows SharePoint Services 3
Event Category: Runtime
Event ID: 6611
Date: 1/15/2009
Time: 1:11:26 PM
User: N/A
Computer: [MACHINE NAME]
Description:
Error: Failure in loading assembly: [AssemblyName], Version=1.0.0.0, Culture=neutral, PublicKeyToken=e376b6bc65267f90

It's worth mentioning that these errors mentioned the names of assemblies that were used in multiple sites (even though they were deployed into bin folders). The sites that used these assemblies were customized, and their Master Pages and Page Layouts referenced the assemblies that supposedly couldn't be loaded (as far as the error was concerned. Some of these dependencies were strong named and others were not. None of them lived in the GAC (all bin folder deployed).

The Solution

We used the fact that the errors occurred every 15 minutes to link them to Quick Deploy jobs. When we changed the quick deployments to every 10 minutes, the errors followed suit reoccurring at the same interval.

At this point we were convinced that the SharePoint Timer (OWSTimer.exe) was trying to load these assemblies butEssential .NET Volume 1 couldn't find them. So how does assembly resolution happen in the .NET framework? We were saved by an an excerpt from Essential .NET, Volume 1: The Common Language Runtime, a book by Don Box and Chris Sells. Essentially it works like this.

  1. When the assembly loader goes to load an assembly, it first looks to whether the assembly is strong named. If it IS, then the loader first looks in the GAC (not the bin folder).
  2. If it can't find the assembly in the GAC, the loader will then look for <codeBase> hints in the applications configuration file. Remember that these settings inherit down from machine.config to app.config/web.config.
  3. If there's no <codeBase> hints then the loader will resort to probing as a last ditch effort to find the assembly. This includes bin folders and any other location dictated by <probing> elements.

If the above seems confusing, consider the following flow chart.Flow chart speaking to assembly resolution.

We first tried putting hints in the local web.configs, but because the OWSTimer has nothing to do with the our applications, the settings were being ignored. We finally helped the timer out by making the following modifications to the machine.config. To ensure that we didn't remap ALL lookups for the given assembly to the specific location, we had any other application who used the same assembly name override these settings below with a similar one in their own web.config. The overridden setting listed a location that made more sense for the particular web application (ie. web applications should go hunting for .dll's in their own bin folder, not some other applications).

The machine.config was changed to read:

<runtime>  
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="[NameOfAssembly]" publicKeyToken="9871993fa258bc6" culture="neutral" />
<codeBase version="1.0.0.0" href="file://C:/folder/directory/bin/[NameOfAssembly].dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>

The web.config was changed to read:

<runtime>  
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="[NameOfAssembly]" publicKeyToken="9871993fa258bc6" culture="neutral" />
<codeBase version="1.0.0.0" href="file://C:/webapplicationLocation/bin/[NameOfAssembly].dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>

You can also provide <codeBase> hints for assemblies that aren't strongly named, you just need to omit the the optional publicKeyToken and culture attributes. Another tip is that you can also use the <probing> element if you want to probe folders other than the bin folder.

We then restarted IIS, followed by the timer service. Low and behold, our random error went away. This toast goes out to the highly configurable .NET framework, and the expressiveness of app/web/machine.config files.

Best,
Tyler

Tuesday, January 27, 2009

TroubleShooting The JQuery Accordion

JQuery and the Accordion

I've been getting more and more into JQuery recently. It's light, free (as in freedom), and has a vibrant community. Sweetening the deal is the ever growing list of animated controls that effortlessly plug into the framework.

We've been using JQuery for quite a few of our clients who have expressed a desire for more interactive SharePoint sites. I've been so impressed with the framework of late that I've started to advocate it over heavier tools that try to achieve similar results.

The Problem

Just today I ran into a pretty interesting problem with the JQuery Accordion. I'm throwing up this fix because I couldn't find a solution on the web. We had the accordion binding off of a SiteMapDataSource in a SharePoint master page, everything looked great in Chrome, FireFox, and Safari...but IE 6 and 7 were giving us a really hard time.

What made this even more frustrating is that it worked fine in at least three other SharePoint sites with exceedingly similar master pages.

The accordion would flicker at the end of the animation every time the user would expand or collapse a sub menu. We tried removing all the CSS, but the page still yielded the same behavior. The menu would briefly flash the entire contents of a sub menu whenever a a new section was collapsed/expanded. The only way we could stop this was by turning the animation off in entire.

The Troubleshoot

At first I tried debugging the JavaScript for JQuery and the accordion, but the source quickly became difficult to follow. The guys who wrote this stuff have mad JavaScript skills, they're head over heels better JavaScript developers than I am.

So I ended up doing what I normally do when I don't understand what's going on. I started to make things simpler. I opened up SharePoint Designer and started removing sizeable sections of the page, block by block, seeing if I could get the problem to go away. I ended up with a ridiculously small html document that basically had the the accordion menu markup and a couple of other html tags.

It was only when the document was about forty lines long that the problem became apparent.

There was no doc type on the html document. I've written about Quirks Mode before, so I was a little embarrassed that I hadn't noticed it earlier. If you're not familiar, or are too lazy to click on the link above, in a nutshell quirks mode is a special rending mode that browsers go to when you either don't specify the doc type or use html that deviates from the declared doc type. The rules for what justifies quirks mode rendering changes from browser to browser. For IE, not declaring a doc type will cause it to render the page in quirks mode.

Quirks mode changes the way that the browser handles CSS rules. When we failed to declare a doc type, IE started rendering the menu in quirks mode. This changed the way that the browser handled the in line CSS that the JQuery accordion was tacking onto menu list markup. Hence the odd behavior.

I added my favorite and most relaxed doc type:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Low and behold, the animation issue went away. Quirks mode strikes again. I guess the lesson here is that before you get to involved in a markup troubleshoot, ensure the document isn't being rendered in quirks mode! You can figure out how to detect quirks mode by reading this.

Fool Me Twice,
Tyler

Thursday, January 22, 2009

SharePoint: Searching With Managed Properties

Crawled and Managed Properties

When the SharePoint 2007 crawler indexes a piece of content, it finds a not only a bunch of text to index, but also a tonne of metadata about the document. These pieces of metadata are referred to as crawled properties. Consider an Office 2007 Word document (.docx). When the crawler opens up the document, it finds a plethora of information about the file; the file extension, who authored it, when it was created, and the actual text in the document itself. These are just some the many crawled properties captured about any given piece of content. What fields actually get captured are a function of the content and the IFilter that helped the crawler dissect the document.

Here's a reduced screen cap of some of the crawled properties captured for Office Documents. Crawled properties (for Office documents) captured by the SharePoint CrawlerYou can sift through all the properties that are being captured by your crawler by going to the Shared Service Provider, then clicking on Search Settings, Metadata property mappings and then on Crawled Properties. If you click on the Office category you'll end up getting a list that's much longer than the abridged one on the right. Whenever the crawler discovers a new property, it adds the new crawled property to a list maintained in the Shared Service provider. If the property discovered is of type text, then it is automatically added to the search index.

It's important to note that a Crawled Property can be reused in many Managed Properties, and Managed Properties can have mappings from many Crawled Properties (many to many). In fact this is how we harvest value from the Crawled/Managed property marriage. By using them together we can construct extremely powerful and expressive search queries.

Managed Properties are user created labels, that map one or more crawled properties to a searchable term. They are available for basic search, advanced search and for defining scopes. An example of a search expression using a managed property might be the search:

Title:"Tyler"

When I search Title:"Tyler" (read [ManagedProperty]:"[SearchTerm]"), I'm really searching all the crawled properties that are mapped to the managed property Title, for the text "Tyler".

That is, the search expression Title:"Tyler" will bring back all the search results that have the text "Tyler" in at least one of the following crawled properties [Mail:5(Text), People:PreferredName(Text), Basic:displaytitle(Text), ows_Title(Text)]. In fact if you feel that the crawled properties attached to Title aren't sufficient, you can make any changes you want. Managed properties are there for you to explore and tweak.

Creating a Managed Property

You don't really have a lot of control over crawled properties (you simply get what the indexer picks up). You do however get a fair bit of hand over what managed properties exist, and what crawled properties are mapped to them. It's worth mentioning that you don't always need to install a new IFilter to get more crawled properties to show up. The indexer will also pick up custom site columns that you add to your lists/libraries every time it does a full crawl. If this site column has never been seen before (ie. you just created it), a new entry will be added to the crawled properties list.

A good example of this would be if you were to create a new site column (say MyCustomeField) on some list. The nextCreating a Managed Property using a crawled property discoverd from a custom data type. time the indexer does a full crawl, the new crawled property will show up (named ows_MyCustomeField). You can then open up Metadata Property Mappings (from the Shared Service Provider Search Settings) and create a new managed property (say TylersCustomField) that users can use to search exactly that site column. They could, for exaple search for TylersCustomeField:"SomeValue". You can even use that managed property to limit or grow the search results that are governed by any search scope.

When you start to digest the utility of Managed/Crawled properties, it becomes apparent they they're responsible for a huge part of the SharePoint search's expressiveness. They empower you to help users author some pretty functional searches. Not just the kind of searches that find all the documents with a certain file extension (fileextension:"doc", but searches that look only at very custom properties within niche types of content.

Consider the following out of the box managed properties that allow searching for people by their assistant's name (Assistant:"Mary"), by their Responsibilities (Responsibilities:"Sales"), or finding files by filename (filename:"my document"). Managed properties can also be grouped in searches (fileextension:"doc" filename:"my document").

Stop by the Managed Properties pages in the Shared Services Provider and you'll be impressed. Once you start to wrap your head around managed properties, you'll realize how easy it is to leverage this out of the box functionality for your customers. You'll may even start to feel like SharePoint is finally making your job easier.

Best,
Tyler

Sunday, January 18, 2009

Turn On The Search Already!

ROI Unleashed

When IT departments roll out SharePoint, search is usually the last thing on their minds. This is really a shame, because powerful enterprise search is one of the most underutilized features that comes out of the box with MOSS Standard or Enterprise. You get search with WSS too, but you can only search a given site collection.

MOSS allows you to search across a whole enterprise unifying rogue document shares, reclusive business data, and your actual SharePoint content. People can also search for People and find internal resources that possess a particular skill set, or report to a given manager.

Business units naturally tend to carve out their own space for storing tribal knowledge. This is usually irritating to system administrators and confusing to new hires (never mind existing employees). One of the easiest corrective actions is to tell SharePoint to go index all these pieces of hidden content and yield them when the appropriate search string is entered.

Creating a search portal is one of the most obvious value adds that you can quickly provide your users. I can't think of any organization I've ever worked with that didn't have documents scattered across the enterprise. In a day and age when IT is constantly trying to justify it's ROI, turning the key on enterprise search is an easy home run.

What's even better is that SharePoint Search will automatically security trim based on ACL (Access Control List) entries that are found on the content. Microsoft Office SharePoint 2007 Administrators CompanionThis means that if you're indexing an NTFS share that only the DOMAIN\HR users can access, you don't have to worry about the search engine yielding those documents as search results when searches are done by the DOMAIN\Marketing folks. This holds true for SharePoint content which also exposes ACLs to the SharePoint indexer.

If you're completely new to search, consider reading the search chapters in Bill English's Microsoft Office SharePoint Server 2007 Administrator's Companion. While it's not specifically geared to search, it'll speak to search in general and all the topics directly related to search. It's probably the most complete SharePoint reference out there. I like to think of it as the MOSS Bible for all things general and out of the box. If you're looking for a more in depth title more specifically targeted to search, consider Inside the Index and Search Engines: Microsoft Office SharePoint Server 2007 (PRO-Developer).

Fire It Up

If you haven't done so already, consider creating a portal site for your enterprise. After that, create a Search Center somewhere off that root site.

All that's left to do is open up the Shared Service Provider for your farm and start adding content sources. After you perform a full crawl, a myriad of documents that used to be extremely hard to find (or at least required Sherpa like navigation knowledge) will start to show up as search results for anyone who had access in the first place. Start small if you have a tonne of content to index and aren't currently in a large farm set up, but have a little faith in the product too. Even a stand alone installation can easily maintain an index for thousands of documents, and when you need to scale your farm out, rest assured that it's very possible. 2009.01.18 22.02.49

If you're part of a huge organization then search becomes a more interesting topic in the sense that indexing millions of documents and setting up the security around all this content is a big job. But the point of this post is to make you more aware of SharePoint search and took at it as a relatively easy value add. Take comfort in the fact that this out of the box search feature (MOSS Standard/Enterprise) will do things that even $10,000 Google Mini's won't. You owe it to yourself to at least start playing with it.

In future posts we'll get into Managed and Crawled Properties, search Scopes, Content Sources etc..., the purpose of this is simply to get you enthused about search. There's no replacement for good planning and a solid information taxonomy, but when information is already scattered to the winds nothing helps round up lost documents like a good search engine.

Good Luck,
Tyler

Thursday, January 15, 2009

STSADM Restore Errors With SQL SERVER Express

But There's Tonnes of Disk Space!

The other day I was migrating a site collection from one machine to another. I had a copy of the source site collection and was ready to restore it on this new machine that another developer had prepped. I created a SharePoint web application at the destination and then proceeded to run the restore command:

stsadm -o restore -url http://someurl -filename c:\file.bak -overwrite

After a while I ended up getting some disgruntled feedback from the stsadm tool:

The site collection could not be restored. If this problem persists, please make sure the content databases are available and have sufficient free space.

Which was confusing, I made sure there was tonnes of disk space (20 GB free for the restore of a 3 GB site collection) and tried again...it died with the same error. After poking around I noticed something odd after running the following query in the Management Studio:

SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')

As it turns out, the database server I was trying to restore the site collection into was running SQL Server Express Edition which has a file size cap of 4 GB. When this "farm" was set up, it was done so with a Basic install which by defaul installs SQL Express and inherits it's limitations. The site collection I was trying to restore was breaking the 4 GB limit and as a result the stsadm tool thought there wasn't any disk space available, when really there was a bunch to be had..

Upgrading SQL Server Express to Developer/Standard/Workstation/Enterprise

As a result I had to upgrade the OFFICESERVERS instance of SQL Server running on that machine from Express to Developer (you can upgrade it to Developer/Standard/Workstation/Enterprise, whatever you have in terms of media/licensing).

This ends up being pretty easy, you simply find the media/installer and run the setup.exe that you normally would but with an added argument of SKUUPGRADE=1.

setup.exe SKUUPGRADE=1

When the install wizard gives you get a chance, select the OfficeServers instance and upgrade the database engine. If you want a more detailed walkthrough, one is available here. When you're done, run the same SQL query above and the product edition should no longer be Express.

After that small adventure, the restore worked like a charm.

Hope that helps someone.

Best,
Tyler

Tuesday, January 13, 2009

Big Fat Content Deployment Jobs

The Blessings and Woes of Content Deployment

If you've spent a lot of time dealing with Incremental Content Deployment Jobs, then you've most likely either developed the patience of a saint, or a taste for 80 proof liquor.

This particular feature has worked, and then not worked over a series of SharePoint patches. For example, it didn't work under RTM for many sites, then a hot fix corrected the behavior. It was then broken again for most web applications under service pack one, which was followed by a fix in the Infrastructure Update.

Because this particular feature has dealt the world so much hair loss, a lot of clients I've met with have resorted to using full content deployment jobs to get their content from one site collection to another.

The key difference between the two is that an incremental deployment job will deploy only changes (new records, updates, and deletes). A full content deployment job will deploy everything in the site/branch/site collection that you select (that is, it will deploy a copy of the current version, not the version history as well). If you select a site, you're about to get another copy of every asset in that site. If you select the entire site collection, there's even more content that's about to get duplicated.

Hold Off On That Full Content Deployment

The real problem with resorting to full content deployments is that if you're prone to using them too often your content database size can go through the roof. For those who normally deal with SharePoint capacity and planning, this can be a nightmare. The last thing you want is bloated a content database with duplicate copies of 40 MB PowerPoint presentations coupled with the HR departments prized PDF collection.

A particular client we work with ended up using full content deployments for sub sites about 6 months ago because they couldn't get incremental content deployments to work. Before they knew it their destination site collection was 16 times the size of the source site collection. Luckily this particular content database was pretty lean (about 150 MB, and so the destination only ended up being ~2.5 GB). Imagine if they had a source site collection that was around 50 GB (which is very common for many intranet site collections), they'd be looking at a destination site collection which would be ~ 0.8 TB, a near unmanageable (or at least painful) amount of data for most small to medium IT shops.

No one really wins when it comes to regular full content deployments. Even if there's quotas on the site collection the inherent duplication still steals space that users could otherwise use to store useful data. If patching it isn't something you feel you can easily do yourself consider contacting MS SharePoint Support, they're not half bad, and they're pretty cheap ($250 last time I checked).

If you're not already convinced, here's a couple screen caps of data pulled from  Red Gate SQL Data Compare detailing the differences on just a small site. The first cap is a before/after comparison of a sub site being deployed using an incremental job after a small change as taken place (content edit).

The second screen cap is of the same site before/after a full content deployment job targeting the same sub site.

Record Difference Before and After an Incremental Content Deployment

 SQLCompareIncremental

Record Difference Before and After a Full Content DeploymentSQLCompareFull

These results will of course dramatically change with the site of your site collection and what you're doing a full content deployment on. The point is just to offer a reminder that the unnatural growth of the content database just may not be worth it in the long run. If you're currently wed to full content deployments I'd suggest either getting a divorce ASAP, or investing in some sizable disks to help manage the data explosion.

Buying more disks,
Tyler

Wednesday, January 7, 2009

Don't Rule Out MS Support For Help

Someone Call Redmond

SharePoint 2007 has been out for over two years now. Even though I'm a fan of the product, I'd be the last one to tell you that there haven't been glaring bugs with some of the more prominent features. The good news is that over time, hot fix by hot fix, these are slowly getting resolved.

Depending on what you've been using SharePoint for, your mileage may have varied significantly. Until a couple days ago, all of the solutions and workarounds I'd ever applied to the product had come from forums, blogs, white papers, and books. Last week we ran into a problem that we’d flailed at for long enough and decided to enlist the help of Microsoft Support. This is a recount of that experience.

Issues with Content Deployment

We were running MOSS 2007 SP1 and were having problems with incremental content deployments. We were considering deploying the SharePoint Infrastructure Update which supposedly addresses the issue. We were reluctant to deploy the updated because of the related downtime our farm would incur (this particular farm is public facing and gets tens of thousands of visitors a day). If possible we wanted to find another way.

So we decided we’d push the problem onto The Soft and let MS Support deal with it. $250 later, a support ticket was opened. Contrary to the complaints I’d found online there was little to no wait, and within a couple business days someone from MS Support was calling me every morning asking me when we could start working on the ticket.

Although it was probably a different story when the product first launched, it doesn’t seem like there are Black Friday style wait lists for support these days. We also read this post by Eric to help us properly characterize the problem for MS Support. It’s of note that even though we provided a fair amount of detail in the opening emails, I ended up repeating the details back to the support agent anyways.

The troubleshoot went surprisingly well. The support engineer was attentive to our concerns and very thorough in her diagnosis. Although she had a very distinct accent, she was on our time zone (PST) and had exceptional product knowledge. What’s even better is they were willing to work around my extremely varied schedule and were relatively high touch. Someone from the support team phoned and emailed me at least every day, even if I forgot to return their emails. At times I felt like they wanted to fix our issues more than we did. All in all I’d give the experience an 8/10 and recommend it to anyone who feels like they’re grasping at straws.

The money ($250) is relatively cheap compared to your time, and you’ll get a chance to ask a ton of product related questions. What’s even better is that if your problem ends up being fixed by a patch (hot fix/update/service pack) or is related to a product deficiency (you use a work around to resolve it) there’s a strong chance that you’ll be refunded the $250. Ultimately the decision is supposed to be up to the support engineer’s manager. All this is from the mouth of a support engineer, so give it the same credence as you would most hearsay.

I guess the point of all this is to not rule out MS Support when it comes to SharePoint issues. By all means exhaust your regular avenues first, but don’t be afraid to ask for help from Microsoft Support when you start to feel all alone. The process requires a lot of patience, but depending on the problem it may be the cheapest way to fix the problem. Ideally having good support is one of the reasons your company decided to go with a well known vendor in the first place.

One Less Problem,
Tyler