I have a dev org, in which I have got a namespace prefix. In apex, I want to get this namespace prefix as string. Is there any straight way or I have to describe some object?
3 Answers
Query for it, using a class that you know will be there:
ApexClass myClass = [
select NamespacePrefix
from ApexClass
where Name = 'SomeClassNameHere'
];
-
-
Hm good question. I think it should just work for all users when queried from Apex, but you'd want to test that to be sure. May 7, 2016 at 5:10
Spotted in the Spring `16 release notes under Changed Objects:
Organization
The following new fields have been added:
- NamespacePrefix
- SignupCountryIsoCode—Represents the two-character ISO country code specified by the user for a sign-up request.
It appears it will now be possible to directly query for the NamespacePrefix without needing to have a known Apex Class or Trigger present.
Here's a technique to get the namespace without invoking SOQL.
// PageReference behavior is different between managed and unmanaged code.
// In managed code it modifies the URL to add the namespace to the page URL,
// so /apex/page becomes /apex/MY_NAMESPACE__page.
String namespaceOfMyManagedPackage =
new PageReference('/apex/page')
.getUrl()
.replaceFirst('^/apex/', '')
.replaceFirst('page$', '')
.replaceFirst('__$', '');
// For example, if you are in a managed package (or the packaging org) this
// will return 'MY_NAMESPACE', but if this is in unmanaged code it will
// be a blank/empty string
UPDATE
Here is a less hacky way to get the namespace. Extract it directly from the Type name:
// Experiment in Execute Anonymous Apex
String namespaceOfClass = AssertException.class.getName().substringBefore('AssertException').split('\\.')[0];
System.debug('CORRECT: ' + AssertException.class + '->' + namespaceOfClass);
//Output: 'CORRECT: System.AssertException->System'
Note: When you are extracting the namespace from inner types, to correctly get the namespace you must pass the top level class name to substringBefore
.
Here are the experiments to verify it for yourself:
// To run the following experiments, save a New Apex Class 'Foo' in your org
/*
public class Foo { public class InsideFoo {} }
*/
// Experiments in Execute Anonymous Apex
String namespaceOfFoo = Foo.class.getName().substringBefore('Foo').split('\\.')[0];
System.debug('CORRECT: ' + Foo.class + '->' + namespaceOfFoo);
//Output if Foo is in no-namespace class: 'CORRECT: Foo->'
//Output if Foo is in 'mynamespace' managed package: 'CORRECT: mynamespace.Foo->mynamespace'
String namespaceOfFooFromInsideFoo = Foo.InsideFoo.class.getName().substringBefore('Foo').split('\\.')[0];
System.debug('CORRECT: ' + Foo.InsideFoo.class + '->' + namespaceOfFooFromInsideFoo);
//Output if Foo is in no-namespace class: 'CORRECT: Foo.InsideFoo->'
//Output if Foo is in 'mynamespace' managed package: 'CORRECT: mynamespace.Foo.InsideFoo->mynamespace'
// Note that substringBefore needs the top level class name, NOT the inner class, otherwise
// it will not properly determine the class's namespace.
String MAYBETheNamespaceOfFoo = Foo.InsideFoo.class.getName().substringBefore('InsideFoo').split('\\.')[0];
System.debug('MAYBE INCORRECT: '+Foo.InsideFoo.class + '->' + MAYBETheNamespaceOfFoo);
//Output if Foo is in no-namespace class: 'MAYBE INCORRECT: Foo.InsideFoo->Foo'
//Output if Foo is in 'mynamespace' managed package: 'MAYBE INCORRECT: mynamespace.Foo.InsideFoo->mynamespace'