function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nathan ANathan A 

How do I let end-users build Visualforce Pages that use classes installed by my packages?

I have an application that's been installed by one of my clients.  This application includes a Controller Extension that is defined as a global class.

 

I'd like the client to be able to create Visualforce Pages that use that custom Controller Extension.  Currently when they attempt to do this they get the following error:

 

 

	Error: Apex class 'LeadControllerExtension' does not exist

 

When attempting to create the following basic page:

 

 

<apex:page standardController="Lead" extensions="LeadControllerExtension" >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>

 

Any ideas?

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Nathan ANathan A

I still don't know what the best practices are for using the global keyword, but I was finally able to overcome my problem by using dot-notation for the namespace prefix like this:

 

 

<apex:page standardController="Lead" extensions="cellsixtyone.LeadControllerExtension" >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>

 

I never ceased to be amazed how how much of a complete mess the standards and practices are for Apex development.  It's a random hodgepodge of protocols and instruments.

 

Now I'm having a whole new problem surrounding the use of:

 

 

ApexPages.currentPage().getHeaders().get('Host');

 

Wherein I'm making that call inside a Trigger deployed by my package on a Custom Object that's also inside my package, and when that resolves at runtime on the client's instance it returns my developer's account URL rather than the client's instance URL.  Which makes about no sense at all.

 

 

All Answers

Nathan ANathan A

I've tried going to the Version info on the VF page that's being created and including the Package that has the controller extension, and that didn't work.

 

There must be a way to do this.  How does one write VF pages that access objects and classes from installed packages?

tantotanto

I am assuming the installed package is managed. If that is the case there is not a way to access these classes. Manage packages means your code is private and cannot be accessed except by the applications in you managed package.

Nathan ANathan A
Yes it's a managed package. That can't be the case that the end user can't access any of the classes in it from their own code, can it? What's the point if declaring classes as global, and being able to see the method signatures when looking at the Apex class from the org that installed the package? More over, what's the point of being able to explicitly reference an installed packed from the Version tab on a VF page record, or an Apex Class record? I thought the whole point of the "global" keyword was to make classes available outside your application. What you're saying is that it'd be impossible to release an extended class library as a product?
Nick34536345Nick34536345

the client probably just needs to add the namespace prefix.

 

class libraries certainly are possible, see "apex-lang" which I recall you can get as managed or un-managed.

gv007gv007

If you declared class and class members as global you can access out side of a managed package.In yours sample code you did't added the namespace

 

suppose you global class is Myclass

when access in a unmanaged code you need to accees the class namespace__c.MyClass.

 

 

Nathan ANathan A

Hmm.... well if I do this:

 

 

<apex:page standardController="Lead" extensions="cellsixtyone_LeadControllerExtension" >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>

 

 

I get this error:

 

 

Error: Apex class 'cellsixtyone_LeadControllerExtension' does not exist	

 

 

I don't appear to have improved the situation any.  The latest version of my package is added under the "Version Settings" Tab, and I've verified that the method descriptors for the Class are shown when going to the Apex Classes section in Setup and clicking on the LeadControllerExtension entry.

Nathan ANathan A

My LeadControllerExtension Class relies on another Class from my package called DeploymentManager, does that package also have to be flagged as global even though I'm not directly accessing any of its methods from outside the package?

Nathan ANathan A

Making the dependent Class also be set as global (along with its methods) didn't help either.

 

This is beyond aggravating.

Nathan ANathan A

I still don't know what the best practices are for using the global keyword, but I was finally able to overcome my problem by using dot-notation for the namespace prefix like this:

 

 

<apex:page standardController="Lead" extensions="cellsixtyone.LeadControllerExtension" >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>

 

I never ceased to be amazed how how much of a complete mess the standards and practices are for Apex development.  It's a random hodgepodge of protocols and instruments.

 

Now I'm having a whole new problem surrounding the use of:

 

 

ApexPages.currentPage().getHeaders().get('Host');

 

Wherein I'm making that call inside a Trigger deployed by my package on a Custom Object that's also inside my package, and when that resolves at runtime on the client's instance it returns my developer's account URL rather than the client's instance URL.  Which makes about no sense at all.

 

 

This was selected as the best answer
gv007gv007

You are correct.For got to mention in previous post.If you observed after packing components in VF page class are access using namespace.controller name