Bug #4295

How to set Saxon licenseFileLocation in config file programmatically

Added by Kevon Hayes 27 days ago. Updated 13 days ago.

Build and release
Start date:
Due date:
% Done:


Legacy ID:
Applies to branch:
9.9, trunk
Fix Committed on Branch:
9.9, trunk
Fixed in Maintenance Release:


I need to set the licenseFileLocation.

// Doesn't seem to work var pConfig = new ProfessionalConfiguration(); pConfig.setConfigurationProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath);

Previously when licenseFileLocation in the config file is left blank I received and license exception. How do I register this configuration to be used?


#1 Updated by Kevon Hayes 27 days ago

I'd rather set the license config programmatically and NOT via config file

#2 Updated by Kevon Hayes 27 days ago

This seems to work. Is this the recommended way?

ProfessionalConfiguration p = new ProfessionalConfiguration(); p.setConfigurationProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath); p.setProcessor(_processor);

#3 Updated by Michael Kay 26 days ago

The most straightforward way is:

Processor p = new Processor(true);
p.SetProperty(Feature.LICENSE_FILE_LOCATION, saxonLicensePath)

Note however that if you use a configuration file and supply it using the Processor constructor that accepts a configuration file reference, then Saxon needs access to the license file while processing the configuration file, so this approach isn't going to work. In this situation you need to use one of the other mechanisms for locating the license file.

#4 Updated by Kevon Hayes 26 days ago


What about the setProcessor() method? I assumed that is how a configuration gets associated with a Processor. I this correct?

#5 Updated by Michael Kay 26 days ago

No, the primary reference is from the Processor to the Configuration, and this is always established explicitly or implicitly when tbe Processor is created. The method Configuration.setProcessor() sets a field in the Configuration for the reverse link; this is never used internally within Saxon, but it's available for applications, e.g. in an extension function you might have access to the XPathContext and this enables you (usually) to get back to the originating Processor. It's not 100% reliable because it's possible for a Configuration to be used by (say) a s9api Processor, a .NET Processor, a JAXP TransformerFactory, and a JAXP SchemaFactory simultaneously, and Configuration.getProcessor() can only get you back to one of these.

#6 Updated by Kevon Hayes 26 days ago


How do I do this. I need to ensure the processor is associated with our PE configuration.

#7 Updated by Michael Kay 26 days ago

Normally you would create the Processor and this would create the Configuration automatically.

On the Java side it's also possible to create the Configuration first, and then create a Processor over that Configuration. That doesn't appear to be possible on the .NET side, so you have to allow the Processor to create the Configuration, which you can then access as the Implementation property of the Processor.

#8 Updated by Kevon Hayes 26 days ago

Then how does the Processor know to use the HE configuration cs the PE configuration? I'm not using a config file.

I need this to be correct:

public static Processor GetConfiguredProcessor()
            var saxonLicensePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data\\licenses\\saxon-license.lic");

            var processor = new Processor(true);
            processor.SetProperty("", "false");

            var saxonPEConfig = new ProfessionalConfiguration();
            saxonPEConfig.setConfigurationProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath);

            return processor;

#9 Updated by Kevon Hayes 26 days ago

I hope you see I'm trying to ensure the processor is using the PE config. I'll change my code accordingly.

#10 Updated by Kevon Hayes 26 days ago

If you do not recollect our conversation... in a different ticket you told me to ensure my processor is using my config. Now all I'm asking is how to do that. What is the purpose of creating a ProfessionalConfiguration if I cannot ensure a processor is being used by it?

#11 Updated by Kevon Hayes 23 days ago


Remember I am limited because I have to pass in a URI to the Processor which points to a config file, which in-turn needs a URI for the licenseLocation field.

I'm on .NET and you know the exceptions I've run into in utilizing the SaxonAPI with having to pass in URIs to methods and constructors that are UNC paths. I cant use a config file because I need to programtically set the licenseLocation and I can't use ProfessionalConfiguration because I can't set a Processor with it.

Since I can access the Configuration object in .NET I will try passing my Processor to it.

I hope you next version addresses these issues. I've notice this UNC issue has been a known issue since November of 2007 and it is still not fixed.

#12 Updated by Michael Kay 23 days ago

I'm going to review these threads with my colleagues when we're all back in the office after the summer break tomorrow. It's been a bit hampered by the fact that we've been scattered around geographically. I think it might be a good idea to schedule a teleconference with yourselves as well.

#13 Updated by Kevon Hayes 22 days ago


That would indeed be great! Just let me know the time and my team and I will join the call.

#14 Updated by Kevon Hayes 22 days ago

I realized that I didn't need this:

var saxonPEConfig = new ProfessionalConfiguration();
saxonPEConfig.setConfigurationProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath);

// I'm using this instead
processor.SetProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath);

#15 Updated by Michael Kay 21 days ago

I think what we're still missing here is that you can either specify a configuration file (in the appropriate variants of new Processor()), or you can specify a license file location using processor.SetProperty(FeatureKeys.LICENSE_FILE_LOCATION, saxonLicensePath), but you can't do both: if Saxon is building a configuration from a configuration file then it generally needs access to the license file while doing so, and the call on SetProperty will come too late.

One way of tackling this would be to allow the configuration file to contain syntax such as `licenseFileLocation="$SAXON_HOME/saxon-license.lic" to signal that the license file location is obtained by consulting an environment variable (here SAXON_HOME).

#16 Updated by Michael Kay 20 days ago

I've been looking at the various ways a Configuration and Processor can be built, with a view to tidying things up a little for the next major release. I want to avoid over-complicating the s9api interface; specialist requirements can be met by building a Configuration manually, and then wrapping a Processor around it.

One of the more specialised ways of building a configuration is the static method Configuration.readConfiguration(configFile, baseConfig); which takes selected properties from the configuration file and other details from the base configuration. I'm changing this so the license details are taken from the base configuration if available (in which case any licenseFileLocation in the configuration file is ignored).

In cases where a license file location is supplied dynamically, or where the configuration is activated using the API made available to holders of redistribution licenses, this allow the sequence

ProfessionalConfiguration A = new ProfessionalConfiguration();
A.setLicenseFileLocation()  ... or ... A.supplyLicenseKey();
Configuration B = Configuration.readConfiguration(configFile, A);
Processor P = new Processor(B);

The only change needed to make this work is for the configuration created by Configuration.readConfiguration(configFile, A) to inherit the licensing details known to A (which is currently done manually by the only caller of this interface, namely the fn:transform() function). So I will make that change by patch.

#17 Updated by Michael Kay 20 days ago

  • Category set to Build and release
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Priority changed from High to Normal
  • Applies to branch trunk added
  • Fix Committed on Branch 9.9, trunk added

#18 Updated by O'Neil Delpratt 13 days ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release added

Bug fix applied in the Saxon maintenance release.

Please register to edit this issue

Also available in: Atom PDF