为什么我的Java / SalesForce应用程序由于安全限制而无法创建JAXBContext?

时间:2011-01-22 23:48:26

标签: java web-services soap jaxb salesforce

我在一个Java/Salesforce tutorial但我无法让它按原样工作,因为SoapBindingStub似乎是基于折旧库的过时代码。所以我尝试使用JAX-WS Quick Start中的代码对代码进行网格划分,但这也没有用。无论我做了什么,最终样本控制台应用程序都会遇到异常,抱怨“ Web服务异常创建salesface端口:由于类javax.xml.ws.WebServiceException 的安全限制,无法创建JAXBContext ”

我放弃了(暂时)尝试将两个代码混合在一起,而现在正在努力抽象JAX-WS Quickstart.java,这样我就能理解它的工作原理并在其他应用程序中重用它的方法。

无论我如何对代码进行切片和切块,它总是卡在相同的位置,基本上会出现同样的错误。

以下是持久失败的方法的当前代码:

private void initPort() 
{
    try 
    {
        URL wsdlLocation = this.getClass().getClassLoader().getResource("META-INF/enterprise.wsdl");
        if (wsdlLocation == null) 
        {
            WebServiceException webServiceException = new WebServiceException("enterprise.wsdl not found!");
            ExceptionToolkit.display("Web Service Exception can't find enterprise.wsdl", webServiceException);
            throw webServiceException;
        }
        else {System.out.println("\nFOUND enterprise.wsdl!!!\n\n");}

        QName qName = new QName("urn:enterprise.soap.sforce.com", "SforceService");
        SforceService sforceService = new SforceService( wsdlLocation, qName );
        System.out.println("\nsforceService INITIALIZED. About to get Soap.\n\n");
        Soap soap = (sforceService).getSoap();
        System.out.println("\nWe have soap.\n\n");
        setPort (soap);
    } 
    catch (WebServiceException webServiceException) 
    { 
        ExceptionToolkit.display("Web Service Exception creating salesface port", webServiceException); 
        return;
    }
}

这是错误,包括紧接在之前和之后的输出:

Running main loop



FOUND enterprise.wsdl!!!



sforceService INITIALIZED. About to get Soap.




Web Service Exception creating salesface port: Unable to create JAXBContext due to the security restriction
on class javax.xml.ws.WebServiceException
javax.xml.ws.WebServiceException: Unable to create JAXBContext due to the security restriction
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:131)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:63)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:224)
    at com.sun.xml.ws.client.WSServiceDelegate.addSEI(WSServiceDelegate.java:588)
    at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:291)
    at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:274)
    at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:267)
    at javax.xml.ws.Service.getPort(Unknown Source)
    at com.sforce.soap.enterprise.SforceService.getSoap(SforceService.java:53)
    at hu.flux.salesforce.LoginToolkit.initPort(LoginToolkit.java:78)
    at hu.flux.salesforce.LoginToolkit.doLogin(LoginToolkit.java:122)
    at hu.flux.salesforce.LoginToolkit.<init>(LoginToolkit.java:49)
    at hu.flux.salesforce.samples.Quickstart.mainLoop(Quickstart.java:55)
    at hu.flux.salesforce.samples.Quickstart.<init>(Quickstart.java:28)
    at hu.flux.salesforce.samples.Quickstart.main(Quickstart.java:21)
Caused by: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
    this problem is related to the following location:
        at java.lang.StackTraceElement
        at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
        at java.lang.Throwable
        at java.lang.Exception
        at com.sforce.ws.ConnectionException
        at com.sforce.ws.SoapFaultException
        at com.sforce.soap.enterprise.fault.ApiFault
        at public javax.xml.bind.JAXBElement com.sforce.soap.enterprise.fault.ObjectFactory.createFault(com.sforce.soap.enterprise.fault.ApiFault)
        at com.sforce.soap.enterprise.fault.ObjectFactory
com.sforce.ws.types.Time does not have a no-arg default constructor.
    this problem is related to the following location:
        at com.sforce.ws.types.Time
        at public com.sforce.ws.types.Time com.sforce.soap.enterprise.sobject.BusinessHours.getFridayEndTime()
        at com.sforce.soap.enterprise.sobject.BusinessHours
        at public com.sforce.soap.enterprise.sobject.BusinessHours com.sforce.soap.enterprise.sobject.ObjectFactory.createBusinessHours()
        at com.sforce.soap.enterprise.sobject.ObjectFactory

    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:124)
    ... 14 more
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
    this problem is related to the following location:
        at java.lang.StackTraceElement
        at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
        at java.lang.Throwable
        at java.lang.Exception
        at com.sforce.ws.ConnectionException
        at com.sforce.ws.SoapFaultException
        at com.sforce.soap.enterprise.fault.ApiFault
        at public javax.xml.bind.JAXBElement com.sforce.soap.enterprise.fault.ObjectFactory.createFault(com.sforce.soap.enterprise.fault.ApiFault)
        at com.sforce.soap.enterprise.fault.ObjectFactory
com.sforce.ws.types.Time does not have a no-arg default constructor.
    this problem is related to the following location:
        at com.sforce.ws.types.Time
        at public com.sforce.ws.types.Time com.sforce.soap.enterprise.sobject.BusinessHours.getFridayEndTime()
        at com.sforce.soap.enterprise.sobject.BusinessHours
        at public com.sforce.soap.enterprise.sobject.BusinessHours com.sforce.soap.enterprise.sobject.ObjectFactory.createBusinessHours()
        at com.sforce.soap.enterprise.sobject.ObjectFactory

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:422)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:270)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:103)
    at com.sun.xml.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:89)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:126)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:125)
    ... 16 more



1. Login
2. Get Accounts
3. Update Accounts
4. Get Server Timestamp
5. Exit
Enter a menu option: 

堆栈上引用我自己的代码的最后一行(按时间顺序排列)是:

at hu.flux.salesforce.LoginToolkit.initPort(LoginToolkit.java:78)

源代码中的System.out.println语句确认这是执行终止的内容。这一行特别指出:

Soap soap = (sforceService).getSoap();

有谁知道这样做或为什么会超越安全限制,最终让java无法创建JAXBContext?

3 个答案:

答案 0 :(得分:1)

我终于有登录工作了......对于我开始工作的第一个教程以及从JAX WS Quickstart派生的拼接代码。如果它对任何人有帮助,这是我完整的LoginToolkit类。 (对不起,当我没有得到我的时间或输出报酬时,我对评论有点懒惰。)

/**
 * 
 */
package hu.flux.salesforce;

import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;

import hu.flux.exceptions.ExceptionToolkit;
import hu.flux.input.PromptUser;

import com.sforce.soap.enterprise.InvalidIdFault;
import com.sforce.soap.enterprise.LoginResult;
import com.sforce.soap.enterprise.SessionHeader;
import com.sforce.soap.enterprise.SforceService;
import com.sforce.soap.enterprise.Soap;
import com.sun.xml.bind.api.JAXBRIContext;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;

/**
 * @author Brian Kessler
 *
 */
public class LoginToolkit {

    private Soap binding = null;
    private LoginResult loginResult = null;;

    public void setBinding(Soap binding) { this.binding = binding; }
    public Soap getBinding() { return binding; }

    public void setLoginResult(LoginResult loginResult) { this.loginResult = loginResult; }
    public LoginResult getLoginResult() { return loginResult; }

    /**
     * 
     */
    public LoginToolkit() { doLogin(); }

    private boolean doLogin()
    {   
        //String userName = getUserInput("Enter user name: ").trim();
        //String password = getUserInput("Enter password: ").trim();
        String userName = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        String password = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        binding = bindEnterpriseWSDL();

        System.out.println("LOGGING IN NOW....");
        try { loginResult = binding.login ( userName, password ); }
        catch (InvalidIdFault invalidIdFault) { return loginExceptionCaught("invalid id fault", invalidIdFault); }
        catch (com.sforce.soap.enterprise.LoginFault loginFault) { return loginExceptionCaught("login fault", loginFault); }
        catch (com.sforce.soap.enterprise.UnexpectedErrorFault unexpectedErrorFault) { return loginExceptionCaught("unexpected error fault", unexpectedErrorFault); }

        // Check if the password has expired
        return (loginResult.isPasswordExpired()) ? passwordExpired() : bindSession();
    }

    private Soap bindEnterpriseWSDL()
    {
        try 
        {
            URL wsdlLocation = this.getClass().getClassLoader().getResource("META-INF/enterprise.wsdl");
            if (wsdlLocation == null) 
            {
                WebServiceException webServiceException = new WebServiceException("enterprise.wsdl not found!");
                ExceptionToolkit.display ("Web Service Exception could not find enterprise.wsdl.", webServiceException);
                throw new WebServiceException(webServiceException);
            }
            else { System.out.println ("\n\n\nenterprise.wsdl WAS found!\n\n\n");}

            QName qName = new QName("urn:enterprise.soap.sforce.com", "SforceService");
            SforceService sforceService = new SforceService(wsdlLocation, qName);
            Soap soap = sforceService.getSoap();
            return soap; 
        } 
        catch (WebServiceException webServiceException) 
        {
            ExceptionToolkit.display ("Web Service Exception creating salesface port.", webServiceException);
            throw new WebServiceException(webServiceException);
        }
    }


    private WSBindingProvider enableGzip(BindingProvider bindingProvider) 
    {
        //Enable GZip compression
        Map<String, List<String>> httpHeaders = new HashMap<String, List<String>>();
        httpHeaders.put("Content-Encoding", Collections.singletonList("gzip"));
        httpHeaders.put("Accept-Encoding", Collections.singletonList("gzip"));
        Map<String, Object> reqContext = bindingProvider.getRequestContext();
        reqContext.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
        return (WSBindingProvider) bindingProvider;
    }

    private boolean passwordExpired() 
    {
        System.out.println("An error has occured.  Your password has expired.");
        return false;
    }   

    private boolean bindSession() 
    {
        //binding._setProperty(Soap BindingStub.ENDPOINT_ADDRESS_PROPERTY, loginResult.getServerUrl());
        WSBindingProvider bindingProvider = ((WSBindingProvider) binding);
        bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, loginResult.getServerUrl());
        bindingProvider = enableGzip (bindingProvider);

        // Create a new session header object and add the session id from the login return object
        SessionHeader sessionHeader = new SessionHeader();
        sessionHeader.setSessionId(loginResult.getSessionId());
        bindingProvider = setJAXBContext (bindingProvider, sessionHeader);


        reportLoginSuccess();

        return true; // return true to indicate that we are logged in,  pointed at the right url and have our security token in place.
    }   

    private WSBindingProvider setJAXBContext (WSBindingProvider bindingProvider, SessionHeader sessionHeader) 
    {
        JAXBContext jc;
        try { jc = JAXBContext.newInstance("com.sforce.soap.enterprise"); } 
        catch (JAXBException jaxbException) 
        {
            ExceptionToolkit.display ("Error creating JAXBContext instance.", jaxbException);
            throw new WebServiceException(jaxbException);
        }

        bindingProvider.setOutboundHeaders(Headers.create((JAXBRIContext) jc, sessionHeader));
        return bindingProvider;
    }

    private void reportLoginSuccess() 
    {
        System.out.println("Login was successfull.");
        System.out.print("The returned session id is: ");
        System.out.println(getLoginResult().getSessionId());
        System.out.print("Your logged in user id is: ");
        System.out.println(getLoginResult().getUserId() + " \n\n");
    }

    private boolean loginExceptionCaught(String label, Exception exception) 
    { 
        ExceptionToolkit.display ("A " + label + " has occured.", exception);
        return false;
    } 

    public boolean checkLogin() 
    {
        // check to see if we are already logged in
        if (this.getLoginResult() == null) 
        {
            System.out.println("Run the login sample before the others.\n");
            PromptUser.getUserInput("Hit enter to continue: ");
            System.out.println("\n");
            return false;
        }
        return true;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {}

}

答案 1 :(得分:0)

您似乎正在尝试创建一个在其合同中具有java.lang.ExceptionStackTraceElement子类的Web服务。你不能这样做。处理异常的唯一方法是使用错误。

你是否在Salesforce之外完成了所有这些工作?

请注意,您的代码在手动初始化JAXB上下文时会遇到麻烦,但是您没有将其传递到JAX-WS调用中,因此堆栈正在创建新的JAXB上下文并且在尝试时遇到了麻烦。您是否记得将其传递给绑定提供程序,如...

 try {
        jc = JAXBContext.newInstance("com.salesforce.sei");
        bindingProvider.setOutboundHeaders(Headers.create((JAXBRIContext) jc, sh));
    } catch (JAXBException e) {
        System.out.println("Error creating JAXBContext instance " + e.getMessage());
        return false;
    }

答案 2 :(得分:0)

如果您想使用Jax-WS,请参阅Jax-WS/salesforce quickstart,这里有一长串java samples for salesfoce on the wiki