• toddnewman
  • NEWBIE
  • 25 Points
  • Member since 2010

  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 8
    Questions
  • 7
    Replies

I recently created a template and set up a workflow to send it under certain criteria.  When I asked the user to test it, she complained that the fonts were wonky.  They had looked fine to me but the forwarded email was undeniable.  What I determined is that if I edited the template on mac/chrome, the resulting email looked fine in Mac/Outlook but not Windows/Outlook.  But if I edited the template on Windows/Chrome, the resulting email looked fine on both.

 

FYI, on the Mac I was copying the text in from TextWrangler (I also tried Fraise) both are plain text editors.  I also selected all the text in the SFDC editor and set the font and size after the fact.  No combination of those actions fixed the problem.  On Windows, I copied the text from the Notepad++ editor.

 

Screenshots are below.  Has anyone seen this?  Maybe even found a workaround?  TIA!

 

BTW, the Lead first name is a play off a joke from the TV show "New Girl," I'm not trying to be insensitive.  Also, if there is are Admin boards where this would be appropriate please let me know.

 

Mac version - wonky fonts

 

 

Windows version - consistant fonts

 

 

Hi again.  I have discussed this problem previously.  Incidentally, I can't duplicate the problem in the same way anymore but that's not the important story for today.


Sadly, my full codebase (as opposed to the contrived class) was still throwing the same error...even after I made sure all the class versions were up in the 20s.  But after much tedious debugging I have found another problem.  And a spoiler...there are more problems to find.  I still get the error if I run my "real" code.  But this one is verifiable so I thought I'd share it now.


If you send an email too soon before you make a callout, you will get the "uncommitted work" error.  I often debug code by sending myself emails with state, especially messy code like this with future calls and such.  Unfortunately for me, if I'm having trouble with a callout, one thing I'm going to want to know is what arguments I am sending out!  So naturally I had emailing code right before my callout.


What I am finding is that if the email is near the callout in code (and presumably execution time) I get the error.  This contrived class is not long enough to really demonstrate it.  But if I had a couple hundred lines of code with some SELECT statements I could email out inside the future method context without error.  For this class I demonstrated by putting the "safe" email before the future call.

 

}

public with sharing class EmailBeforeCalloutIssue {

 

// alter the static vars and then run this line anonymous

//EmailBeforeCalloutIssue.makeItHappen();

 

    private static Boolean I_LIKE_SUCCESS = true;

    private static String EMAIL_ADDR = 'your_email_address__________';

 

    public static void makeItHappen() {

 

        Map<String, String> params = new Map<String, String>();

        EmailBeforeCalloutIssue.buildParams(params);

        String qs = makeStringFromMap(params);

 

        // ****** emailing HERE (far from .send) is not a problem

        if (EmailBeforeCalloutIssue.I_LIKE_SUCCESS) EmailBeforeCalloutIssue.sendDebugEmail('The Dude perseveres.');

 

        EmailBeforeCalloutIssue.makeItHappenCallout(qs);

 

    }

 

    @future(callout=true)

    public static void makeItHappenCallout(String qs) {

 

        // ****** emailing HERE (too close to .send) causes failure

        // it's possible to email successfuly after we've entered the future as long as there is sufficient delay such as database reads

        if (!EmailBeforeCalloutIssue.I_LIKE_SUCCESS) EmailBeforeCalloutIssue.sendDebugEmail('an occasional acid flashback...');

 

        Http h = new Http();

        HttpRequest req = new HttpRequest();

        req.setEndpoint('https://secure.future.stage.ariasystems.net/api/ws/api_ws_class_dispatcher.php');

        req.setMethod('POST');

        req.setBody(qs);

 

        String debugString = 'TTN: ';

        try {

            HttpResponse res = h.send(req);

            debugString = debugString + 'success! ' + res.getBody();

 

        } catch (Exception e) {

            debugString = debugString + 'error! ' + e.getMessage();

        }

 

        // tell me the result, I need to know!

        EmailBeforeCalloutIssue.sendDebugEmail(debugString);

 

    }

 

    public static void sendDebugEmail(String body) {

        Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();

        mail2.setToAddresses(new String[] {EmailBeforeCalloutIssue.EMAIL_ADDR});

        mail2.setCcAddresses(new String[] {});

        mail2.setReplyTo('noreply@salesforce.com');

        mail2.setSenderDisplayName('Salesforce');

        mail2.setSubject('Salesforce debug');

        mail2.setBccSender(false);

        mail2.setUseSignature(false);

        mail2.setPlainTextBody(body);

        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail2 });

    }

 

    private static void buildParams(Map<String, String> params) {

 

        EmailBeforeCalloutIssue.putParam(params, 'email', '');

        EmailBeforeCalloutIssue.putParam(params, 'city', 'Del Mar');

    // etc

 

    }

 

    private static String makeStringFromMap(Map<String, String> params) {

        String res = '';

        for (String key : params.keySet()) {

            res += key + '=' + EncodingUtil.urlEncode(params.get(key), 'UTF-8') + '&';

        }

 

        res = res.substring(0, res.length() - 1);

        return res;

    }

 

    public static void putParam(Map<String, String> params, String paramName, String paramValue) {

        if (paramValue != null) {

            params.put(paramName, paramValue);

        } else {

            params.put(paramName, '');

        }

    }

 

===================================================

S2S does not automatically keep relationships intact. There is a workaround posted here but I couldn't get it to work for lead conversion.

 

The problem with the above workaround is that account synchronization needs to be fully established before we can get the information we need to set up the relationships in the client org. Since account/contact/opportunities are created almost simultaneously on conversion that is no good. I tried several variations with code in one org or the other to no avail. Those three objects are simply created more quickly than the synch is completed. So I resorted to scheduled Apex.

 

Using scheduled Apex from a trigger has some gotchas. Job names must be unique and you can only have 20 scheduled jobs at one time. Not to mention you can't query the status of jobs by ID or name.

 

I use a custom object to keep track of which records still need to be synchronized and which jobs they are attached to (within some hack-y reason). You could use custom fields instead but I think the custom object is a little cleaner.

 

This is not fully debugged and the error handling is incomplete. I noticed that if I convert a second lead before the first one is done, I get two scheduled jobs. But that does not lead to an error so I let it be.

 

Hope this helps some folks out there.

 

 

================== Custom Object ==================

S2SParentPropogation__c

JobID__c, Text(18)

LocalAccountId__c, Text(18)

LocalId__c, Text(18)

Status__c, Picklist (values of Inserted, Completed, Error)

===================================================

 

================= Contact Trigger =================

trigger Contact_AfterInsert on Contact (after insert) {

 

  S2S_EstablishPropogation prop = new S2S_EstablishPropogation();

  prop.createContactSyncJob(Trigger.new);

 

}

===================================================

 

================= Opportunity Trigger =================

trigger Opportunity_AfterInsert on Opportunity (after insert) {

 

  S2S_EstablishPropogation prop = new S2S_EstablishPropogation();

  prop.createOpportunitySyncJob(Trigger.new);

 

}

=======================================================

 

============ S2S_EstablishPropogation Class ============

public class S2S_EstablishPropogation {

 

  public void createContactSyncJob(List<Contact> contacts) {

 

    // init

    List<PartnerNetworkRecordConnection> newSynchRecords = new List<PartnerNetworkRecordConnection>();

    List<Contact> toSynchLater = new List<Contact>();

    S2S_Utils su = new S2S_Utils();

 

    // build list of account IDs

    List<ID> localAccountIds = new List<ID>();

    for (Contact c : contacts) {

      localAccountIds.add(c.AccountId);

    }

 

    // figure out which of the parent accounts have been synced already

    List<PartnerNetworkRecordConnection> findSynchedAccounts = su.findAlreadySynchedAccounts(localAccountIds);

    Set<ID> synchedLocalAccounts = buildSetOfLocalAccountIds(findSynchedAccounts);

 

    // process those contacts who's accounts have been synced and store the rest for later

    for (Contact c : contacts) {

      // if the parent account has already been synched, we can save ourself some work later

      if (synchedLocalAccounts.contains(c.AccountId)) {

        // connection record will auto-share this contact with the client org

        newSynchRecords.add(su.buildPartnerConnectionRecord(c.Id, c.AccountId));

 

      // no joy, log this to a table to synch later

      } else { toSynchLater.add(c); }

    }

    // insert those we can now

    insert newSynchRecords;

 

    // now create records for later syncing

    if (toSynchLater.size() > 0) {

      // make sure there's a job in the future to process the records we're about to create

      String jobId = findOrCreateJobThatEstablishesSharesLater('003');

 

      // finally, create record of opportunities to sync

      List<S2SParentPropogation__c> deferredSyncRecords = new List<S2SParentPropogation__c>();

      for (Contact c : toSynchLater) {

        deferredSyncRecords.add(createSyncLaterRecord(c.Id, c.AccountId, jobId));

      }

      insert deferredSyncRecords;

    }

 

  }

 

  public void createOpportunitySyncJob(List<Opportunity> oppts) {

 

    // init

    List<PartnerNetworkRecordConnection> newSynchRecords = new List<PartnerNetworkRecordConnection>();

    List<Opportunity> toSynchLater = new List<Opportunity>();

    S2S_Utils su = new S2S_Utils();

 

    // build list of account IDs

    List<ID> localAccountIds = new List<ID>();

    for (Opportunity o : oppts) {

      localAccountIds.add(o.AccountId);

    }

 

    // figure out which of the parent accounts have been synced already

    List<PartnerNetworkRecordConnection> findSynchedAccounts = su.findAlreadySynchedAccounts(localAccountIds);

    Set<ID> synchedLocalAccounts = buildSetOfLocalAccountIds(findSynchedAccounts);

 

    // process those opporunities who's accounts have been synced and store the rest for later

    for (Opportunity o : oppts) {

      // if the parent account has already been synched, we can save ourself some work later

      if (synchedLocalAccounts.contains(o.AccountId)) {

        // connection record will auto-share this oppt with the client org

        newSynchRecords.add(su.buildPartnerConnectionRecord(o.Id, o.AccountId));

 

      // no joy, log this to a table to synch later

      } else { toSynchLater.add(o); }

    }

    // insert those we can now

    insert newSynchRecords;

 

    // now create records for later syncing

    if (toSynchLater.size() > 0) {

      // make sure there's a job in the future to process the records we're about to create

      String jobId = findOrCreateJobThatEstablishesSharesLater('006');

 

      // create record of opportunities to sync

      List<S2SParentPropogation__c> deferredSyncRecords = new List<S2SParentPropogation__c>();

      for (Opportunity o : toSynchLater) {

        deferredSyncRecords.add(createSyncLaterRecord(o.Id, o.AccountId, jobId));

      }

      insert deferredSyncRecords;

    }

 

  }

 

  private String scheduleJob(String objectType) {

    Integer rand = Crypto.getRandomInteger();

    String ran = String.valueOf(rand).substring(5);

    S2S_Utils su = new S2S_Utils();

    String sch = su.getScheduleStringMinutesFromNow(S2S_Utils.SCHEDULE_JOB_HOW_MANY_MINUTES_IN_FUTURE);

    S2S_PropogateParent prop = new S2S_PropogateParent();

    return System.schedule('S2S sync-' + objectType + '-' + ran, sch, prop);

  }

 

  private Set<ID> buildSetOfLocalAccountIds(List<PartnerNetworkRecordConnection> findSynchedAccounts) {

    Set<ID> synchedLocalAccounts = new Set<ID>();

    for (PartnerNetworkRecordConnection a : findSynchedAccounts) {

      synchedLocalAccounts.add(a.LocalRecordId);

    }

    return synchedLocalAccounts;

  }

 

  private String findOrCreateJobThatEstablishesSharesLater(String objectType) {

 

    String jobId = 'addon';

 

    // find already scehduled jobs

    // we can't query directly so we have to make use of our own stored IDs

    Datetime wasCreatedAtOrAfter = Datetime.now().addSeconds(30).addMinutes(-3);

    List<S2SParentPropogation__c> existingJobs =

      [SELECT Id FROM S2SParentPropogation__c

      WHERE JobID__c != null

      AND JobID__c != 'addon'

      AND Status__c = 'Inserted'

      AND CreatedDate > :wasCreatedAtOrAfter];

 

    if (existingJobs.size() == 0) {

      // nothing is scheduled, create a job

      jobId = scheduleJob(objectType);

    }

 

    return jobId;

 

  }

 

  private S2SParentPropogation__c createSyncLaterRecord(ID child, ID parent, String jobId) {

    return new S2SParentPropogation__c(

      LocalId__c = child,

      LocalAccountId__c = parent,

      Status__c = 'Inserted',

      JobID__c = jobId

    );

  }

 

}

====================================================

 

============ S2S_PropogateParent Class ============

global class S2S_PropogateParent implements Schedulable {

 

  global void execute(SchedulableContext SC) {

 

    S2S_Utils su = new S2S_Utils();

 

    // clear out previously completed records

    Datetime hourAgo = DateTime.now().addHours(-1);

    List<S2SParentPropogation__c> deleteNow = [SELECT Id FROM S2SParentPropogation__c WHERE Status__c = 'Completed' AND CreatedDate < :hourAgo];

    try {

      delete deleteNow;

    } catch (Exception e) {

      // meh, it was probably already deleted by another job running in parallel

    }

 

    /****************** Retrieve Data **********************/

    // what records are out there awaiting sync

    Datetime minsAgo = DateTime.now().addMinutes(-1);

    List<S2SParentPropogation__c> processNow =

      [SELECT LocalId__c, LocalAccountId__c, Status__c

      FROM S2SParentPropogation__c

      WHERE Status__c = 'Inserted'

      AND (JobID__c = 'DOH-testing' OR CreatedDate < :minsAgo)];

 

    // get list of accounts so we know which sync records to look for

    List<ID> localAccountIds = new List<ID>();

    for (S2SParentPropogation__c pp : processNow) {

      localAccountIds.add(pp.LocalAccountId__c);

    }

 

    // which of those accounts have completed sync?

    List<PartnerNetworkRecordConnection> findSynchedAccounts = su.findAlreadySynchedAccounts(localAccountIds);

 

    /****************** Add Sync Records **********************/

    List<PartnerNetworkRecordConnection> newSynchRecords = new List<PartnerNetworkRecordConnection>();

    for (S2SParentPropogation__c p : processNow) {

 

      // find corresponding account S2S sync record

      PartnerNetworkRecordConnection accountS2S = null;

      for (PartnerNetworkRecordConnection pn : findSynchedAccounts) {

        if (pn.LocalRecordId == p.localAccountId__c) {

          accountS2S = pn;

        }

      }

 

      // found it

      if (accountS2S != null) {

        // auto-share this contact/opportunity with the client org

        newSynchRecords.add(su.buildPartnerConnectionRecord(p.LocalId__c, p.LocalAccountId__c));

        p.Status__c = 'Completed';

      }

    }

 

    insert newSynchRecords;

    update processNow;

 

  }

 

}

===================================================

 

================= S2S_Utils Class =================

public class S2S_Utils {

 

  public static Integer SCHEDULE_JOB_HOW_MANY_MINUTES_IN_FUTURE = 3;

  public static String CONNECTION_NAME = '[Connection Name]';

 

  public List<PartnerNetworkRecordConnection> findAlreadySynchedAccounts(List<ID> localAccountIds) {

    // find accounts that have already been synched

    return [SELECT Id, ConnectionId, PartnerRecordId, LocalRecordId

      FROM PartnerNetworkRecordConnection

      WHERE LocalRecordId in :localAccountIds

      AND (Status ='Sent' OR Status = 'Received')];

  }

 

  public PartnerNetworkRecordConnection buildPartnerConnectionRecord(ID child, ID parent) {

    return new PartnerNetworkRecordConnection (

      ConnectionId = getConnectionId(),

      LocalRecordId = child,

      ParentRecordId = parent,

      SendClosedTasks = false,

      SendOpenTasks = false,

      SendEmails = false

    );

  }

 

  public ID getConnectionId() {

    List<PartnerNetworkConnection> partnerNetConList =

      [SELECT id FROM PartnerNetworkConnection

      WHERE connectionStatus = 'Accepted'

      AND connectionName = :S2S_Utils.CONNECTION_NAME];

 

    if (partnerNetConList.size() != 0) {

      return partnerNetConList.get(0).Id;

    }

 

    return null;

  }

 

  public String getScheduleStringMinutesFromNow(Integer mins) {

    Datetime runTime = Datetime.now().addMinutes(mins);

    return twoDigit(runTime.second()) + ' ' + twoDigit(runTime.minute()) + ' ' + twoDigit(runTime.hour()) + ' ' + twoDigit(runTime.day()) + ' ' + twoDigit(runTime.month()) + ' ? ' + runTime.year();

  }

 

  public String twoDigit(integer raw) {

    if (raw < 10 && raw > 0) {

      return '0' + String.valueOf(raw);

    } else {

      return String.valueOf(raw);

    }

  }

 

}

Hi everyone,

 

I've been altering some integration code and now I get the dreaded "You have uncommitted work pending. Please commit or rollback before calling out" message.  This is supposed to indicate I have begun an update or insert and subsequently made a callout.

 

The code I started with is very OO and it's hard to figure out exactly what is getting run when.  So after a while I started copying the code into a refactored base so I can tell exactly what is going on.  I am now at the point where my code has no DML at all, I'm not even doing a select and I still get the error.  Code is below.

 

I have to think one of two things is happening. Either the error message is incorrect or something is "stuck."  I don't have solid evidence for the latter idea but this error message has come and gone a couple of times without any obvious action on my part.

 

As I search this error message I only find people who actually were doing DML before the callout.  Clearly I am not.  Am I special?  I hope someone else has faced this.

 

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

// execute this line in an anonymous block to see the error non-fun

CalloutLaidBare.toddWillMakeItHappen();

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// here's the class

public with sharing class CalloutLaidBare {


    public static void toddWillMakeItHappen() {

        Map<String, String> params = new Map<String, String>();
        params.put('master_plan_no', '10266411');
        params.put('master_plan_units', '1');

        // etc, all hard-coded values

        // normally I'd be parsing values from an opportunity which is why this is seperate from the future method


        String qs = makeStringFromMap(params);  // this works
        CalloutLaidBare.makeItHappenCallout(qs);

 

    }

    @future(callout=true)
    public static void makeItHappenCallout(String qs) {

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('hard-coded endpoint');
        req.setMethod('POST');
        req.setBody(qs);

        try {
            HttpResponse res = h.send(req);

            // why bother parsing, I'll never get here

 

        } catch (Exception e) {
            // email myself e.getMessage() and drown my sorrows in chocolate
        }

    }


}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-



I just completed a pretty good sized project in my sandbox.  I had been running tests individually but I thought I'd try the "Run All Tests" button to see if anything pops up.  5 hours later it has not finished.  This is my second try.  BTW, I have about 700k of code, 35% full.

 

It's not a huge deal, I think everything is good.  It would just be nice to see some confirmation after spending all this time on those required test cases.

 

Anyone else experienced this?

Hi all,

 

I am trying to run a query over SOAP using Java.  I am using the Javaforce tool which bascially packages up the partner WSDL into an axis wrapper for you.  So far so good.

 

I put it all together in Eclipse, run a test class.  All looks good.  Deploy to tomcat and that's where the fun begins.

 

(1) When I start tomcat, the call errors every time I navigate to the page (detail below)

(2) If I rebuild the WAR and restart tomcat it works perfectly every time (so far)

(3) If I do the same but also clean out the tomcat work directory, it fails every time again.

 

The error occurs on the login call.  The error string is java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.  From what I can see, this occurs when tomcat can't find a valid cacerts file.  I would believe that is the problem except that it works sometimes.  Unfortunately, building and starting twice is not a valid workaround for reasons too boring to detail here.

 

This occurs on both Tomcat 5.5 and 7.0, Java 6.  I hope someone has seen this!

 

From com.sforce.soap.partner.SoapBindingStub

==============

        org.apache.axis.client.Call _call = createCall();
        _call.setOperation(_operations[0]);
        _call.setUseSOAPAction(true);
        _call.setSOAPActionURI("");
        _call.setEncodingStyle(null);
        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
        _call.setOperationName(new javax.xml.namespace.QName("urn:partner.soap.sforce.com", "login"));

        setRequestHeaders(_call);
        setAttachments(_call);
  try {        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {username, password});
/////////// error occurs on the above line

 

Here's more of the response from Salesforce

============================


<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server.userException</faultcode>

<faultstring>javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty</faultstring>

<detail><ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1612)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1595)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1172)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
    at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
    at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
    at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
    at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
    at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
    at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.sforce.soap.partner.SoapBindingStub.login(SoapBindingStub.java:2257)
[snip]
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183)
    at java.security.cert.PKIXParameters.&lt;init&gt;(PKIXParameters.java:103)
    at java.security.cert.PKIXBuilderParameters.&lt;init&gt;(PKIXBuilderParameters.java:87)
    at sun.security.validator.PKIXValidator.&lt;init&gt;(PKIXValidator.java:55)
    ... 134 more
</ns1:stackTrace>
<ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">sveltedaddy.local</ns2:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>


I have some Javascript in a visualforce page that looks like this.

 

 ...

jQuery('#previewOrderPane')

   .append('<table id="previewOrderTable"></table>');

...


if (previewUrl != "") {

        previewUrl = '<a href="' + previewUrl + '" target="_blank">Preview...</a>';

}

...

 

But in a browser, this is what I see in the source.

 

 

...
jQuery('#previewOrderPane')
  .append('<table></table>');
...

   if (previewUrl != "") {
     + previewUrl + '">Preview...</a>';
   }
...
Of course that is a syntax error.  If I remove the function containing this block of code, everything is great.  As I add the function back piece by piece it looks good (minus that ID on the table).  But eventually it gets mangled.  Sometimes sooner but always by the time I get to that previewUrl string concatenation.

 

 

Not sure if this is related, but if I edit the page in the Salesforce setup area (rather than Eclipse), I always get this warning:

 

Warning: The element type "param" should be terminated by the matching end-tag "</param>" at line 82

 

Always at line 82.  I don't have a param element on the page.  I can strip the page all the way down to this:

 

<apex:page controller="DirectMailOrderController" title="Marketing Supplies Order" tabStyle="Case" id="mainPage">


<h1>Marketing Supplies Order</h1>

</apex:page>

 

And I still get the same warning thus telling me that it's not invalid xhtml that is the problem.

 

I tried to log in tonight several times with several browsers.  Each time it asked me to create a new profile/name.  (I used to be taoduh.)

 

Not a huge loss but I would have used the links of my recent posts if I had new answers to post to my own problems.

Hi everyone,

 

I've been altering some integration code and now I get the dreaded "You have uncommitted work pending. Please commit or rollback before calling out" message.  This is supposed to indicate I have begun an update or insert and subsequently made a callout.

 

The code I started with is very OO and it's hard to figure out exactly what is getting run when.  So after a while I started copying the code into a refactored base so I can tell exactly what is going on.  I am now at the point where my code has no DML at all, I'm not even doing a select and I still get the error.  Code is below.

 

I have to think one of two things is happening. Either the error message is incorrect or something is "stuck."  I don't have solid evidence for the latter idea but this error message has come and gone a couple of times without any obvious action on my part.

 

As I search this error message I only find people who actually were doing DML before the callout.  Clearly I am not.  Am I special?  I hope someone else has faced this.

 

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

// execute this line in an anonymous block to see the error non-fun

CalloutLaidBare.toddWillMakeItHappen();

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// here's the class

public with sharing class CalloutLaidBare {


    public static void toddWillMakeItHappen() {

        Map<String, String> params = new Map<String, String>();
        params.put('master_plan_no', '10266411');
        params.put('master_plan_units', '1');

        // etc, all hard-coded values

        // normally I'd be parsing values from an opportunity which is why this is seperate from the future method


        String qs = makeStringFromMap(params);  // this works
        CalloutLaidBare.makeItHappenCallout(qs);

 

    }

    @future(callout=true)
    public static void makeItHappenCallout(String qs) {

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('hard-coded endpoint');
        req.setMethod('POST');
        req.setBody(qs);

        try {
            HttpResponse res = h.send(req);

            // why bother parsing, I'll never get here

 

        } catch (Exception e) {
            // email myself e.getMessage() and drown my sorrows in chocolate
        }

    }


}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-



I just completed a pretty good sized project in my sandbox.  I had been running tests individually but I thought I'd try the "Run All Tests" button to see if anything pops up.  5 hours later it has not finished.  This is my second try.  BTW, I have about 700k of code, 35% full.

 

It's not a huge deal, I think everything is good.  It would just be nice to see some confirmation after spending all this time on those required test cases.

 

Anyone else experienced this?

Hi all,

 

I am trying to run a query over SOAP using Java.  I am using the Javaforce tool which bascially packages up the partner WSDL into an axis wrapper for you.  So far so good.

 

I put it all together in Eclipse, run a test class.  All looks good.  Deploy to tomcat and that's where the fun begins.

 

(1) When I start tomcat, the call errors every time I navigate to the page (detail below)

(2) If I rebuild the WAR and restart tomcat it works perfectly every time (so far)

(3) If I do the same but also clean out the tomcat work directory, it fails every time again.

 

The error occurs on the login call.  The error string is java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.  From what I can see, this occurs when tomcat can't find a valid cacerts file.  I would believe that is the problem except that it works sometimes.  Unfortunately, building and starting twice is not a valid workaround for reasons too boring to detail here.

 

This occurs on both Tomcat 5.5 and 7.0, Java 6.  I hope someone has seen this!

 

From com.sforce.soap.partner.SoapBindingStub

==============

        org.apache.axis.client.Call _call = createCall();
        _call.setOperation(_operations[0]);
        _call.setUseSOAPAction(true);
        _call.setSOAPActionURI("");
        _call.setEncodingStyle(null);
        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
        _call.setOperationName(new javax.xml.namespace.QName("urn:partner.soap.sforce.com", "login"));

        setRequestHeaders(_call);
        setAttachments(_call);
  try {        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {username, password});
/////////// error occurs on the above line

 

Here's more of the response from Salesforce

============================


<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server.userException</faultcode>

<faultstring>javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty</faultstring>

<detail><ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1612)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1595)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1172)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
    at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
    at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
    at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
    at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
    at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
    at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.sforce.soap.partner.SoapBindingStub.login(SoapBindingStub.java:2257)
[snip]
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183)
    at java.security.cert.PKIXParameters.&lt;init&gt;(PKIXParameters.java:103)
    at java.security.cert.PKIXBuilderParameters.&lt;init&gt;(PKIXBuilderParameters.java:87)
    at sun.security.validator.PKIXValidator.&lt;init&gt;(PKIXValidator.java:55)
    ... 134 more
</ns1:stackTrace>
<ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">sveltedaddy.local</ns2:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>


I have some Javascript in a visualforce page that looks like this.

 

 ...

jQuery('#previewOrderPane')

   .append('<table id="previewOrderTable"></table>');

...


if (previewUrl != "") {

        previewUrl = '<a href="' + previewUrl + '" target="_blank">Preview...</a>';

}

...

 

But in a browser, this is what I see in the source.

 

 

...
jQuery('#previewOrderPane')
  .append('<table></table>');
...

   if (previewUrl != "") {
     + previewUrl + '">Preview...</a>';
   }
...
Of course that is a syntax error.  If I remove the function containing this block of code, everything is great.  As I add the function back piece by piece it looks good (minus that ID on the table).  But eventually it gets mangled.  Sometimes sooner but always by the time I get to that previewUrl string concatenation.

 

 

Not sure if this is related, but if I edit the page in the Salesforce setup area (rather than Eclipse), I always get this warning:

 

Warning: The element type "param" should be terminated by the matching end-tag "</param>" at line 82

 

Always at line 82.  I don't have a param element on the page.  I can strip the page all the way down to this:

 

<apex:page controller="DirectMailOrderController" title="Marketing Supplies Order" tabStyle="Case" id="mainPage">


<h1>Marketing Supplies Order</h1>

</apex:page>

 

And I still get the same warning thus telling me that it's not invalid xhtml that is the problem.

 

Hi. I tried to 'disable' the default Attachment function of SFDC with the following trigger:
 
Code:
trigger AttachmentDisabler on Attachment (before insert) {
 List<Attachment> atts = Trigger.new;
 for(Attachment a:atts) {
  a.addError('Please use the "Attach(FTP)" button on top of the detail page to attach a file.'); 
 }
}

 
But this does not seem to work. Did I do something wrong or is it impossible this way? Even the debug did not show anything, the trigger does not seem to do anything. Any other ways to disable the normal Attach function of SFDC without removing the entire related list? (want to keep notes function)