Sunday, February 17, 2013

Custom Sharepoint jobs are not shown in the Sharepoint Central Administration

Sharepoint jobs allows you to execute tasks by scheduler, similar to the way how standard Windows scheduler works. You may consider to move time consuming tasks to the job, so they will run asynchronously and won’t affect user experience (e.g. won’t cause Timeout exceptions because of long task processing during synchronous requests). Sharepoint jobs are executed in separate Windows process called owstimer, so they are isolated from the w3wp process which serves your Sharepoint site and in theory won’t affect performance (I wrote in theory because it is always possible to write code which will slow down your site even from separate process. E.g. if it causes a lot of requests to the content database, which is also used from w3wp).

Here is the example of how you can install Sharepoint job which will run nightly between 1 AM and 2 AM via feature receiver:

   1: public class CustomJobEventReceiver : SPFeatureReceiver
   2: {
   3:     public override void FeatureActivated(
   4: SPFeatureReceiverProperties properties)
   5:     {
   6:         try
   7:         {
   8:             var site = properties.Feature.Parent as SPSite;
   9:             if (site == null)
  10:             {
  11:                 // log
  12:                 return;
  13:             }
  14:  
  15:             this.registerJob(site);
  16:         }
  17:         catch (Exception x)
  18:         {
  19:             // log
  20:             throw;
  21:         }
  22:     }
  23:  
  24:     public override void FeatureDeactivating(
  25: SPFeatureReceiverProperties properties)
  26:     {
  27:         try
  28:         {
  29:             var site = properties.Feature.Parent as SPSite;
  30:             if (site == null)
  31:             {
  32:                 return;
  33:             }
  34:  
  35:             this.deleteJob(site.WebApplication.JobDefinitions,
  36:                 Constants.JOB_NAME);
  37:         }
  38:         catch (Exception x)
  39:         {
  40:             // log
  41:             throw;
  42:         }
  43:     }
  44:  
  45:     private void registerJob(SPSite site)
  46:     {
  47:         if (site == null)
  48:         {
  49:             // log
  50:             return;
  51:         }
  52:  
  53:         this.deleteJob(site.WebApplication.JobDefinitions, Constants.JOB_NAME);
  54:  
  55:         var jonDefinition = new CustomJob(Constants.JOB_NAME,
  56:             Constants.JOB_TITLE, site.WebApplication);
  57:         var schedule = new SPDailySchedule();
  58:         schedule.BeginHour = 1;
  59:         schedule.EndHour = 2;
  60:         jonDefinition.Schedule = schedule;
  61:         jonDefinition.Update();
  62:     }
  63:  
  64:     private void deleteJob(SPJobDefinitionCollection jobDefinitions, string jobName)
  65:     {
  66:         foreach (SPJobDefinition job in jobDefinitions)
  67:         {
  68:             if (string.Compare(job.Name, jobName, true) == 0)
  69:             {
  70:                 job.Delete();
  71:             }
  72:         }
  73:     }
  74: }

Class CustomJob in the example above (see line 55) is defined in the custom assembly, probably the same which contains the code of the feature receiver shown above.

After activation of this feature if everything went well you will see your job in the Central administration > Monitoring > Job definitions. However sometimes you may encounter with the problem that your custom Sharepoint jobs are not shown on production, however on your local development environment everything works properly and jobs are displayed there. Why it may occur and how to fix it?

In order to describe the reason I need to provide more background information about Sharepoint jobs mechanism. Very often in Sharepoint development you have several environments:

  • development environment – in most cases it is all in one server, i.e. server which contains all roles: WFE, app server, database server and has Central administration installed on it of course;
  • QA or staging environment – environment , which is similar to the production environment. I.e. it has the same topology and software installed on it. In most cases it is real Sharepoint farm with several WFEs, separate app and db server (real configuration can be different from case to case, but this is common topology). It is used for preliminary testing of new features and user acceptance testing;
  • production – production Sharepoint farm where your site is running, which also has several WFEs, app and db server.

As we can see there is often difference between development and QA/production. On the dev we use single server Sharepoint installation, while on QA/production – real Sharepoint farm with several servers. You may specify on what server you want to execute the jobs in Central Administration > Manage content databases > select specific content database:

image

Dropdown list “Preferred Server for Timer Jobs” contains servers which have WFE role. On the farm environment it can be so that server which has Central Administration, doesn’t have WFE role. E.g. application server may not have WFE role, while CA is still can be used from it. The problem with this configuration is that custom wsp solutions, which you deploy using standard Install-SPSolution cmdlet (or old deploysolution stsadm operation), will be deployed only to those servers which have WFE role. So if your app server is not WFE, custom assemblies won’t be installed to its GAC. This is exact reason of the problem described above. In this case when you open Central Administration > Monitoring > Review job definitions, it sees your custom jobs, but it can’t find the type where job’s code is defined and can’t deserialize it for executing. That’s why it can’t display custom job.

You can fix this problem by manual adding custom assemblies to the app server’s GAC and performing iisreset. But note that in this case they won’t be updated next time you will upgrade your solutions because of the same reason: solutions are not upgraded automatically on the server without WFE role. You will need again manually update them in the GAC. More correct way to fix this issue is to add WFE role to your app server (and not configure app server without WFE role for the new installations). You can do it by Sharepoint Configuration Wizard as described here: Add a Web or application server to the farm. After that solutions will be deployed to the app server and custom jobs will appear in the Central Administration.

Hope this information will be helpful for you.

4 comments:

  1. Great! Other solution is remove the safe controls from package of the timer job project ( if safe controls are dispensable on project )

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. All steps are followed. But couldn't found my timer job in Job list under Central Administration > Monitoring > Review job definitions.
    It is Farm solution.
    I checked in GAC after Deploy from Visual studio. And I found the relevant timer job assembly. Why it is not visible ?

    ReplyDelete
  4. did you do iisreset after installing assembly to the GAC?

    ReplyDelete