Java NoSuchFieldError when using Reflection, BukkitAPI - bukkit

I`m trying to make packet (in bukkit API).However I get a NoSuchFieldException.
public class PacketPlayOutPlayerInfo {
private static final Class<?> packetClass = Reflections.getCraftClass("PacketPlayOutPlayerInfo");
private static final Class<?>[] typesClass = new Class<?>[]{ String.class, boolean.class, int.class };
private static int type = 0;
static {
try {
if (packetClass.getConstructor(typesClass) == null) {
type = 1;
}
} catch (Exception e) {
type = 1;
}
}
public static Object getPacket(String s, boolean b, int i) {
try {
if (type == 0) {
return packetClass.getConstructor(typesClass).newInstance(s, b, i);
}
else if (type == 1) {
Class<?> clazz = Reflections.getCraftClass("PacketPlayOutPlayerInfo");
Object packet = packetClass.getConstructor().newInstance();
Reflections.getPrivateField(clazz, "username").set(packet, s);
Reflections.getPrivateField(clazz, "gamemode").set(packet, 1);
Reflections.getPrivateField(clazz, "ping").set(packet, i);
Reflections.getPrivateField(clazz, "player").set(packet, new OfflineUser(s).getProfile());
if (!b) {
Reflections.getPrivateField(clazz, "action").set(packet, 4);
}
return packet;
}
} catch (Exception e) {
if (FunnyGuilds.exception(e.getCause())) {
e.printStackTrace();
}
}
return null;
}
}
Here`s full error:
[20:25:43] [IndependentThread/WARN]: java.lang.NoSuchFieldException: username
[20:25:43] [IndependentThread/WARN]: at java.lang.Class.getDeclaredField(Unknown Source)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.Reflections.getPrivateField(Reflections.java:123)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28)
[20:25:43] [IndependentThread/WARN]: java.lang.NullPointerException
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43)
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28)
PS: Sorry for my bad english.

The exception seems to be appropriate given that PacketPlayOutPlayerInfo does not define the fields you are attempting to access. Given the choice of field names, I gather that you might be trying to set values for PacketPlayOutPlayerInfo.PlayerInfoData; even so, its field names are obfuscated and must be given as such unless you pass the information as part of its constructor.
Since this question concerns itself with accessing de-compiled proprietary code, I will leave you with these suggestions:
Familiarize yourself with ProtocolLib, as it already does most of the heavy lifting when it comes to managing and tweaking packets.
If you still want to get your hands dirt and DIY, peruse ProtocolLib's source on GitHub.
If you want the nitty-gritty details about Minecraft classes, I suggest using Spigot's BuildTool, if you aren't already. A side effect of the build process are decompiled Minecraft classes (see work/decompileXXX/net/minecraft/server directory thereunder. This info will help you properly implement reflection calls to instantiate classes and modified fields.
In older versions of bukkitapi(1.6-1.7) this code works great.
To use ProtocolLib i must edit many of code. Thic exception is caused by this class or other?
PacketPlayOutPlayerInfo was changed in 1.8 and continues to change. I looked at the 1.8 (farthest I could go back) and 1.11.2 version and there is a world of difference. That is the problem working with classes that are not part of an API. They will change at will and no one will shed a tear if code breaks outside of Minecraft.
While ProtocolLib may also break, its knowledgeable and experienced developers will fix it quick. They must, since many plugins use it to avoid nasty surprises with new Minecraft releases. If ProtocolLib is not your cup of tea, then I suggest you use BuildTools, inspect the decompile class and adjust your code accordingly. Having Minecraft Modern a click away would also be a good thing.

I think you should check the requesting object variable names(your variable should be camel case). Because in api call you must request with the name exactly in api doc.

Related

WinRT | C++ - HTTP Post File - The certificate authority is invalid or incorrect

Basically I have two concerns, however the focus is on how to get around the certification.
I am having a hard time understanding how to make an HTTP post request in WinRT|C++. I have an ASP.Net-6-Web-Api-Project, which I have already been able to communicate with via a Python project and a C++ project (via Curl). I also tested the api via Postman. Every time doing so I had to ignore the validation of certification and it worked fine.
But now I have a WinRT/C++ project and have thrown together the following code. I want to be able to upload a file. In my case it is a point cloud in a .ply syntax as a string.
My Concerns:
In WinRT I got the expected error for invalid/untrusted certification, so I looked up what to do and ended up using IgnorableServerCertificateErrors from HttpBaseProtocolFilter, like you can see at the end of my code. But that did not fix my error. What am I missing? I still get the errors:
WinRT originate error - 0x80072F0D : 'The certificate authority is invalid or incorrect'.
WinRT originate error - 0x80190190 : 'The response status code does not indicate success: 400 ().'.
From the point of view of a developer familiar with WinRT, is the implementation correct in terms of an HTTP post request? Especially the lines
binaryContent.Headers().Append(L"Content-Type", L"image/jpeg"); andHttpContentDispositionHeaderValue disposition{ L"form-data" }; And what are the follow lines for? Is this just about assigning arbitrary names?
disposition.Name(L"fileForUpload");
disposition.FileName(L"test.ply");
Code:
void HL2ResearchMode::SendPLY(std::wstring const& pointCloud)
{
OutputDebugString(L"--- SendPLY()\n");
if (pointCloud.size() == 0)
return;
init_apartment();
auto buffer{
winrt::Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(
pointCloud,
winrt::Windows::Security::Cryptography::BinaryStringEncoding::Utf8
)
};
winrt::Windows::Web::Http::HttpBufferContent binaryContent{ buffer };
// binaryContent.Headers().Append(L"Content-Type", L"text/plain;charset=utf8");
binaryContent.Headers().Append(L"Content-Type", L"image/jpeg");
winrt::Windows::Web::Http::Headers::HttpContentDispositionHeaderValue disposition{ L"form-data" };
//winrt::Windows::Web::Http::Headers::HttpContentDispositionHeaderValue disposition{ L"multipart/form-data" };
binaryContent.Headers().ContentDisposition(disposition);
disposition.Name(L"fileForUpload");
disposition.FileName(L"test.ply");
winrt::Windows::Web::Http::HttpMultipartFormDataContent postContent;
postContent.Add(binaryContent);
winrt::Windows::Web::Http::HttpResponseMessage httpResponseMessage;
std::wstring httpResponseBody;
try
{
// Send the POST request.
winrt::Windows::Foundation::Uri requestUri{ L"https://192.168.178.41:5001/api/meshes/uploadPointCloud" };
winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter myFilter;
auto fu = myFilter.IgnorableServerCertificateErrors();
fu.Append(ChainValidationResult::Expired);
fu.Append(ChainValidationResult::Untrusted);
fu.Append(ChainValidationResult::InvalidName);
fu.Append(ChainValidationResult::InvalidSignature);
fu.Append(ChainValidationResult::InvalidCertificateAuthorityPolicy);
winrt::Windows::Web::Http::HttpClient httpClient(myFilter);
httpResponseMessage = httpClient.PostAsync(requestUri, postContent).get();
httpResponseMessage.EnsureSuccessStatusCode();
httpResponseBody = httpResponseMessage.Content().ReadAsStringAsync().get();
}
catch (winrt::hresult_error const& ex)
{
httpResponseBody = ex.message();
}
std::wcout << httpResponseBody;
}

Unload a dll loaded by a classloader in Java11

I had a scenario where I need to perform database connectivity using Java11 twice using Windows Authentication on SQL server.
Initially, the sqljdbc_auth.dll is loaded for the first call and the connection was successful. But, in order to make the connection second time at a different place, it throws an SQLException saying 'sqljdbc_auth.dll already loaded by another classloader'.
So, I need to unload the dll in between the two calls.
There is an option to do the same till Java8 version by invoking the finalize() on the classloader using reflection mechanism but unable to find an alternative in Java11
Sample code:
Here, I placed the sqljdbc_auth.dll in the PATH and jar named sql_jdbc.jar in the urls list and these are compatible with Java11
private static void loadFile(){
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();;
ClassLoader loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader()); // here, urls is an array and contains only a single sql_jdbc.jar path in it
Thread.currentThread().setContextClassLoader(loader);
Driver driver = (Driver)loader.loadClass("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection connection = driver.connect("jdbc:sqlserver://IP-addr:1433;DatabaseName=db_name;SelectMethod=cursor;integratedSecurity=true", props);
//perform db actions here
Thread.currentThread().setContextClassLoader(currentClassLoader);
unloadDLL("sqljdbc_auth.dll",loader);
}
private synchronized static void unloadDllFile(String dllName, ClassLoader classLoader) throws Throwable {
try {
Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
field.setAccessible(true);
Map<Object, Object> lib = (ConcurrentHashMap<Object, Object>) field.get(classLoader);
Set<Object> keyset = lib.keySet();
for (Object dllpath : keyset) {
if (dllpath.toString().contains(dllName)) {
Object o = lib.get(dllpath);
classLoader = null;
field = null;
lib.remove(dllpath);
keyset.remove(dllpath);
o = null;
System.gc();
}
}
} catch (Exception e) {
System.out.println("Exception in dll is "+e.getMessage());
}
}
There is a similar code in the second component but it throws an exception there.
Exception stacktrace while loading in the second component is:
com.microsoft.sqlserver.jdbc.SQLServerException: This driver is not configured for integrated authentication. ClientConnectionId:d19de7a1-d099-477c-9c18-0c4cd5807f5e
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:2892)
at com.microsoft.sqlserver.jdbc.AuthenticationJNI.<init>(AuthenticationJNI.java:72)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3636)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:3627)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7194)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2935)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2456)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2103)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1950)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1162)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:735)
at sample.java_samples.Sample2.loadFile(Sample2.java:66)
at sample.java_samples.Sample2.main(Sample2.java:23)
Caused by: java.lang.UnsatisfiedLinkError: Native Library C:\Windows\System32\sqljdbc_auth.dll already loaded in another classloader
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2456)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2649)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:829)
at java.base/java.lang.System.loadLibrary(System.java:1867)
at com.microsoft.sqlserver.jdbc.AuthenticationJNI.<clinit>(AuthenticationJNI.java:52)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3635)
... 10 more
Thanks

How to Digitally Sign a SOAP request BODY in ColdFusion?

New one for me: I need to digitally sign and encrypt the body of SOAP request from a ColdFusion client application using a provider-issued certificate. I also need to decrypt the response in order to process it.
I have searched for days an have found nothing. I have found information referencing other languages, but nothing in ColdFusion. If it is not possible to do it natively through the ColdFusion language API, can someone help me with possibly calling the correct Java or .net classes via the 'createObject()' function or any other method you may have?
17SEP2012 - ADDITIONAL INFO:
More Info: Post timed out while I was looking at code. Here is the complete post:
I am consuming a web service, not providing one. I have reached the point where I have the whole thing working, but it only works once through a ColdFusion "createObject" invokation.
Still need help. System: Windows Server 2003 with ColdFusion 9 single server installation.
I used Apache's wss4J library and wrote a simple Java class as the entry point. The custom Java class simply takes the complete SOAP message as a String argument, passes the String to the wss4j DateStamp class, then passes the resulting SOAP parts object to the signature class, then the encryption class. It then returns the signed and encrypted SOAP envelope, which has been converted from a document (SOAP parts) to a String by the PrettyDocumentToString function.
All of this works and I get a SOAP envelope with security header and signed, encrypted body. The problem is that, after restarting the ColdFusion service (single server install on Windows Server 2003), it all works one time, but subsequent runs result in an error occurring within the wss4j signature code. I have even used Winmerge to compare the entire ColdFusion9 directory immediately after restart, immediately after the 1st run, and immediately after the 2nd run. The only differences were in the log files. There were differences in the ColdFusion9\lib\neo-datasource.xml file, but only in the order of a couple of datasource descriptors, not the content.
Below is the code and stack trace:
writeOutputs and writeDumps are only for visualization during debugging.
ColdFusion calling script:
<cfscript>
variables.tempPath = getDirectoryFromPath(getCurrentTemplatePath());
variables.filePath = tempPath & "ASI_source_request_example.xml";
variables.fileContent = FileRead(filePath);
writeOutput("FILECONTENT: <br>");
writeOutput("variables.fileContent);
writeDump(var="#variables.fileContent#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
variables.encSOAP=createobject("java","ProcessIDSRSSOAP").runProcess(fileContent);
writeOutput("<br><br>encSOAP: <br>");
writeOutput(variables.encSOAP);
writeDump(var="#variables.encSOAP#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
</cfscript>
Java class:
import java.io.FileReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.common.SOAPUtil;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.WSSecEncrypt;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecTimestamp;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;
public class ProcessIDSRSSOAP {
private static Crypto crypto = null;
private static Properties properties = new Properties();
private static String user = "";
private static String cryptoPwd = "";
private static WSSecSignature builder = new WSSecSignature();
private static SOAPConstants soapConstants = null;
private final WSSecHeader secHeader = new WSSecHeader();
private Document tsDoc = null;
private Document signedDoc = null;
private Document encryptedDoc = null;
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(ProcessIDSRSSOAP.class);
public ProcessIDSRSSOAP() throws Exception {
WSSConfig.init();
}
/*
* public static void main(String[] args) throws Exception {
* ProcessIDSRSSOAP processor = new ProcessIDSRSSOAP();
* processor.runProcess(args[0]); }
*/
public String runProcess(String inDoc) throws Exception {
// ProcessIDSRSSOAP processor = new ProcessIDSRSSOAP();
// LOG.debug(inDoc);
Class<ProcessIDSRSSOAP> thisClass = ProcessIDSRSSOAP.class;
ClassLoader thisLoader = thisClass.getClassLoader();
URL propertiesURL = thisLoader.getResource("crypto.properties");
String propertiesPath = propertiesURL.getPath();
propertiesPath = propertiesPath.replaceAll("%20", " ");
properties.load(new FileReader(propertiesPath));
user = properties
.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
cryptoPwd = properties
.getProperty("org.apache.ws.security.crypto.merlin.keystore.password");
crypto = CryptoFactory.getInstance("crypto.properties");
builder.setUserInfo(user, cryptoPwd);
builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
SOAPUtil.toSOAPPart(inDoc.trim());
Document PKIDoc = processDoc(inDoc);
String PKIDocString = org.apache.ws.security.util.XMLUtils
.PrettyDocumentToString(PKIDoc);
LOG.debug(PKIDocString);
return PKIDocString;
}
/**
* #param SOAPMsg
* The entire SOAP message as a type String
* #throws Exception
*/
public Document processDoc(String SOAPMsg) throws Exception {
tsDoc = timestampMSG(SOAPMsg);// Time stamp the SOAP String and make it
// a Document type.
secHeader.insertSecurityHeader(tsDoc);// Insert the security header.
soapConstants = WSSecurityUtil.getSOAPConstants(tsDoc
.getDocumentElement());
signedDoc = signBody(tsDoc);// Send the Document on for signing.
encryptedDoc = encryptBody(signedDoc);
return encryptedDoc;
}
/**
* #param msg
* The entire SOAP message as a type String
* #throws Exception
*/
public Document timestampMSG(String msg) throws Exception {
Document doc = SOAPUtil.toSOAPPart(msg);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(300);
Document createdDoc = timestamp.build(doc, secHeader);
return createdDoc;
}
/**
* #param doc
* Expects a SOAP message as a type Document
* #throws Exception
*/
public Document signBody(Document doc) throws Exception {
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart encP = new WSEncryptionPart(soapConstants
.getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),
"");
parts.add(encP);
builder.setParts(parts);
Document signedDoc = builder.build(doc, crypto, secHeader);
return signedDoc;
}
public Document encryptBody(Document doc) throws Exception {
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
.getDocumentElement());
WSSecEncrypt encrypt = new WSSecEncrypt();
encrypt.setUserInfo(user, cryptoPwd);
encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart encP = new WSEncryptionPart(soapConstants
.getBodyQName().getLocalPart(), // define the body
soapConstants.getEnvelopeURI(), "");
parts.add(encP);
encrypt.setParts(parts);
Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
return encryptedDoc;
}
}
ColdFusion Error:
Signature creation failed (Cannot setup signature data structure)
The error occurred in G:/Inetpub/wwwroot/SOAP/index.cfm: line 14
12 : writeDump(var="#variables.fileContent#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
13 :
14 : variables.encSOAP=createobject("java","ProcessIDSRSSOAP").runProcess(fileContent);
15 :
16 : writeOutput("<br><br>encSOAP: <br>");
Stack Trace:
at cfindex2ecfm1134068877.runPage(G:/Inetpub/wwwroot/SOAP/index.cfm:14)
org.apache.ws.security.WSSecurityException: Signature creation failed (Cannot setup signature data structure)
at org.apache.ws.security.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:191)
at org.apache.ws.security.message.WSSecSignature.addReferencesToSign(WSSecSignature.java:409)
at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:381)
at ProcessIDSRSSOAP.signBody(ProcessIDSRSSOAP.java:118)
at ProcessIDSRSSOAP.processDoc(ProcessIDSRSSOAP.java:85)
at ProcessIDSRSSOAP.runProcess(ProcessIDSRSSOAP.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:97)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2360)
at cfindex2ecfm1134068877.runPage(G:\Inetpub\wwwroot\SOAP\index.cfm:14)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:381)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:94)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.CfmServlet.service(CfmServlet.java:200)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
at jrun.servlet.FilterChain.service(FilterChain.java:101)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Caused by: java.lang.NullPointerException
at org.apache.ws.security.message.DOMCallbackLookup.getElements(DOMCallbackLookup.java:94)
at org.apache.ws.security.util.WSSecurityUtil.findElements(WSSecurityUtil.java:267)
at org.apache.ws.security.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:156)
... 43 more
Obviously, something is missing from org.apache.ws.security.message.DOMCallbackLookup.getElements.
The code feeding it is:
return callbackLookup.getElements(part.getName(),part.getNamespace());
I can't seem to figure out why it works the first time when called from CF, but fails with this error on subsequent runs.
The actual issue was that I had my function calls reversed. I reversed the order of the block
signedDoc = signBody(tsDoc);// Send the Document on for signing.
encryptedDoc = encryptBody(signedDoc);
to
encryptedDoc = encryptBody(signedDoc);
signedDoc = signBody(tsDoc);// Send the Document on for signing.
and it worked.
You would need to add a handler, have a look here as I believe this is similar to what you are trying to achieve: http://milanchandnacf.blogspot.co.uk/2011/09/adding-handler-to-coldfusion-web.html

Add SOAP header object using pure JAX-WS

I'm trying to implement simple web service client for PayPal Express Checkout API using JAX WS. PayPal Express Checkout API provides WSDL file, from which I was able to generate Java classes using CXF's wsdl2java utility.
From authentication reasons, it demands adding SOAP Header to each request. This header is quite simple and should look like here:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECSOAPAPIBasics#id09C3I0CF0O6
Generated from WSDL classes include ebay.apis.eblbasecomponents.CustomSecurityHeaderType class which represents header which I need to add to each request.
So the question is: how can I add manually created instance of CustomSecurityHeaderType class to SOAP request's header taking into account following conditions:
I'm not very eager to use classes from com.sun.* package as mentioned in answer here: JAX-WS - Adding SOAP Headers (mainly because of possible portability issues between different JDK's)
I don't want to manually marshal that object into nested javax.xml.soap.SOAPElement instances as mentioned in answer here:
How do I add a SOAP Header using Java JAX-WS
So, it looks like I've found possible answer while combining JAX-WS & JAXB related answers from SO (I would really appreciate if somebody experienced in these technologies can check whether following is correct):
The obvious thing for me is to add SOAP message handler and alter header of SOAPMessage instance in it:
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.soap.SOAPHeader;
import ebay.api.paypalapi.ObjectFactory; // class generated by wsdl2java
// following class is generated by wsdl2java utility Service class
final PayPalAPIInterfaceService payPalService = new PayPalAPIInterfaceService();
final PayPalAPIAAInterface expressCheckoutPort = payPalService.getPayPalAPIAA();
final Binding binding = ((BindingProvider) expressCheckoutPort).getBinding();
List<Handler> handlersList = new ArrayList<Handler>();
// now, adding instance of Handler to handlersList which should do our job:
// creating header instance
final CustomSecurityHeaderType headerObj = new CustomSecurityHeaderType();
final UserIdPasswordType credentials = new UserIdPasswordType();
credentials.setUsername("username");
credentials.setPassword("password");
credentials.setSignature("signature");
headerObj.setCredentials(credentials);
// bookmark #1 - please read explanation after code
final ObjectFactory objectFactory = new ObjectFactory();
// creating JAXBElement from headerObj
final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);
handlersList.add(new SOAPHandler<SOAPMessageContext>() {
#Override
public boolean handleMessage(final SOAPMessageContext context) {
try {
// checking whether handled message is outbound one as per Martin Strauss answer
final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(requesterCredentials, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
// ... default implementations of other methods go here
});
// as per Jean-Bernard Pellerin's comment setting handlerChain list here, after all handlers were added to list
binding.setHandlerChain(handlersList);
Explanation of bookmark #1:
one should marshal not the header object itself, but JAXBElement representing that object, because otherwise one will get an exception. One should use one of ObjectFactory classes which are generated from WSDL for creating needed JAXBElement instances from original objects.
(Thanks #skaffman for answer: No #XmlRootElement generated by JAXB )
One should also refer to Martin Straus answer which extends this one
This solution works great, but there's a catch. It generates this error when the inbound message is processed:
dic 19, 2012 7:00:55 PM com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl addHeader
SEVERE: SAAJ0120: no se puede agregar una cabecera si ya hay una
Exception in thread "main" javax.xml.ws.WebServiceException: java.lang.RuntimeException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:167)
at com.sun.xml.ws.handler.HandlerTube.processResponse(HandlerTube.java:174)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1074)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:979)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:950)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:825)
at com.sun.xml.ws.client.Stub.process(Stub.java:443)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:174)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:102)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:154)
at $Proxy38.wsRdyCrearTicketDA(Unknown Source)
at ar.com.fit.fides.remedy.api.ws.ServicioCreacionTickets.crearTicket(ServicioCreacionTickets.java:55)
at ar.com.fit.fides.remedy.api.ws.ConectorRemedyWS.crearTicket(ConectorRemedyWS.java:43)
at ar.com.fit.fides.remedy.api.ws.ConectorRemedyWS.main(ConectorRemedyWS.java:90)
Caused by: java.lang.RuntimeException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:50)
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:23)
at com.sun.xml.ws.handler.HandlerProcessor.callHandleMessageReverse(HandlerProcessor.java:341)
at com.sun.xml.ws.handler.HandlerProcessor.callHandlersResponse(HandlerProcessor.java:214)
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:161)
... 14 more
Caused by: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl.addHeader(EnvelopeImpl.java:128)
at com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl.addHeader(EnvelopeImpl.java:108)
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:45)
So, the solution is to check whether the message being handled if the outbound message, like this:
public boolean handleMessage(SOAPMessageContext context) {
try {
Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(AuthenticationInfo.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(info, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
I created a web service exposing method with params user and password as header like this:
#WebService(serviceName="authentication")
public class WSAuthentication {
String name = null;
String password = null;
public WSAuthentication() {
super();
}
public WSAuthentication(String name, String password) {
this.name = name;
this.password = password;
}
private static String getData(WSAuthentication sec) {
System.out.println("********************* AUTHENTICATION ********************" + "\n" +
"**********USER: " + sec.name + "\n" +
"******PASSWORD: " + sec.password + "\n" +
"******************************** AUTHENTICATION ****************************");
return sec.name + " -- " + sec.password;
}
#WebMethod(operationName="security", action="authenticate")
#WebResult(name="answer")
public String security(#WebParam(header=true, mode=Mode.IN, name="user") String user, #WebParam(header=true, mode=Mode.IN, name="password") String password) {
WSAuthentication secure = new WSAuthentication(user, password);
return getData(secure);
}
}
Try compiling it and testing generated from WSDL class. I hope this helps.
I found this answer:
JAX-WS - Adding SOAP Headers
Basically you add -XadditionalHeaders to the compiler options and objects in the headers also appear in your generated code as parameters of the method.
If you are using maven, and the jaxws-maven-plugin all you have to do is add the xadditionalHeaders flag to true and the client will be generated with the methods that have the headers as input.
https://jax-ws-commons.java.net/jaxws-maven-plugin/wsimport-mojo.html#xadditionalHeaders

ArrayOfAnyType issues when calling the method:GetRangeA1 excel web services in the silverlight 4.0

I create a simple silverlight 4.0 application used to read the excel file data in the share point 2010 server. I try to use the "Excel Web Services" but I get an error here when calling the GetRangeA1 method:
An unhandled exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in mscorlib.dll
Additional information: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/office/excel/server/webservices:GetRangeA1Response. The InnerException message was 'Error in line 1 position 361. Element 'http://schemas.microsoft.com/office/excel/server/webservices:anyType' contains data from a type that maps to the name 'http://schemas.microsoft.com/office/excel/server/webservices:ArrayOfAnyType'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'ArrayOfAnyType' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
the source code is like:
namespace SampleApplication
{
class Program
{
static void Main(string[] args)
{
ExcelServiceSoapClient xlservice = new ExcelServiceSoapClient();
xlservice.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Status[] outStatus;
string targetWorkbookPath = "http://phc/Shared%20Documents/sample.xlsx";
try
{
// Call open workbook, and point to the trusted location of the workbook to open.
string sessionId = xlservice.OpenWorkbook(targetWorkbookPath, "en-US", "en-US", out outStatus);
Console.WriteLine("sessionID : {0}", sessionId);
//1. works fines.
object res = xlservice.GetCellA1(sessionId, "CER by Feature", "B1", true, out outStatus);
//2. exception
xlservice.GetRangeA1(sessionId, "CER by Feature", "H19:H21", true, out outStatus);
// Close workbook. This also closes session.
xlservice.CloseWorkbook(sessionId);
}
catch (SoapException e)
{
Console.WriteLine("SOAP Exception Message: {0}", e.Message);
}
}
}
}
I am totally new to the silverlight and sharepoint developping, I search around but didn't get any luck, just found another post here, any one could help me?
This appears to be an oustanding issue, but two workarounds I found so far:
1) Requiring a change in App.config.
http://social.technet.microsoft.com/Forums/en-US/sharepoint2010programming/thread/ab2a08d5-2e91-4dc1-bd80-6fc29b5f14eb
2) Indicating to rebuild service reference with svcutil instead of using Add Service Reference:
http://social.msdn.microsoft.com/Forums/en-GB/sharepointexcel/thread/2fd36e6b-5fa7-47a4-9d79-b11493d18107