ColdFusion, Web Services and SOAP

ColdFusion 30 Comments »

I have been a lot of work with SOAP recently, consuming 3rd party web services written in JAVA and .NET. And I have come to the conclusion that ColdFusion really does suck when it comes to this particular area.

why do I say this, well basically I feel that Adobe have tried to be too clever with the web services and rather than make it easier for CF to work with SOAP they have in fact made it more of a PITA.

 

  1. When you try to consume a web service, the first thing that CF does it download the WSDL and create JAVA stubs for all the methods. This can be the start of your nightmares. Any errors in the WSDL, or anything that JAVA doesn't like, and the stub files will not be created and you will not be able to consume that web service. You also will not get back any kind of remotely useful error message either. So unless the 3rd party is prepared to modify their web service (unlikely) then your screwed. Also the initial request will be very slow while the stubs are generated, and any changes to the WSDL will not be picked up unless you delete the web service definition from the CFADMIN.

    Here is an example of the type of error you might get when the stubs cannot be created.

    coldfusion.jsp.CompilationFailedException: Errors reported by Java compiler: Found 3 semantic errors compiling "/opt/jrun4/servers/cfusion/cfusion-ear/cfusion-war/WEB-INF/cfusion/stubs/WS888823651/fi/atex/www/namespace/Atex/Web/Advertising/Logo/LogoServiceLocator.java": 53. return _stub; <---> *** Error: The type of this return expression, "fi/atex/www/namespace/Atex/Web/Advertising/Logo/LogoSoapBindingStub", does not match the return type of the method, "fi/atex/www/namespace/Atex/Web/Advertising/Logo/Logo". 74. return _stub; <---> *** Error: The type of this return expression, "fi/atex/www/namespace/Atex/Web/Advertising/Logo/LogoSoapBindingStub", does not match the return type of the method, "java/rmi/Remote". 94. return getLogo(); <-------> *** Error: The type of this return expression, "fi/atex/www/namespace/Atex/Web/Advertising/Logo/Logo", does not match the return type of the method, "java/rmi/Remote". Found 1 semantic error co....



  2. Creating a SOAP request in CF can also be a total nightmare as you do it with arrays and structures and CF then tries to convert it into SOAP when you invoke the service. Simple variables are no problem, but when you need to create a request comprising of complex nested variable types, the fun and games begins, as CF just wont produce the required SOAP request in the required format.

    E.G. Here is part of a required SOAP request, generating this in CF as nested structures does not produce the desired result due to the fact it is a nested set of complex variables.

    <insertions>

        <item xsi:type="ns2:insertion">


            <adContent xsi:type="ns2:adContent">

                <color xsi:type="ns2:color" xsi:nil="true"/>

                <id xsi:type="xsd:int">0</id>

                <messages xsi:type="soapenc:Array" xsi:nil="true" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"/>

                <overmatter xsi:type="xsd:boolean">false</overmatter>

                <proofURL xsi:type="xsd:string" xsi:nil="true"/>

                <size xsi:type="ns2:size">

                    <depth xsi:type="xsd:double">30.0</depth><depthUnit xsi:type="xsd:string">mm</depthUnit>

                    <width xsi:type="xsd:double">31.0</width><widthUnit xsi:type="xsd:string">mm</widthUnit>

                </size>

                <styleId xsi:type="xsd:int">509</styleId>

                <text xsi:type="xsd:string">uploadFile26863.tmp</text>

            </adContent>
         </item>
         <item xsi:type="ns2:insertion">


            <adContent xsi:type="ns2:adContent">

                <color xsi:type="ns2:color" xsi:nil="true"/>

                <id xsi:type="xsd:int">1</id>

                <messages xsi:type="soapenc:Array" xsi:nil="true" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"/>

                <overmatter xsi:type="xsd:boolean">false</overmatter>

                <proofURL xsi:type="xsd:string" xsi:nil="true"/>

                <size xsi:type="ns2:size">

                    <depth xsi:type="xsd:double">30.0</depth><depthUnit xsi:type="xsd:string">mm</depthUnit>

                    <width xsi:type="xsd:double">31.0</width><widthUnit xsi:type="xsd:string">mm</widthUnit>

                </size>

                <styleId xsi:type="xsd:int">509</styleId>

                <text xsi:type="xsd:string">uploadFile26863.tmp</text>

            </adContent>
         </item>


    </insertions>


  3. When providing your own web service for others to consume, the SOAP response created by CF is not very developer friendly at all. CF tends to generate xml attributes instead of tag entities.

 

 In all the above situations you are better of manually creating your own SOAP request/response and sending this off the old fashioned way via a cfhttp post, which is in fact also quicker as you are bypassing the java stub files.

Below is an example of manually consuming a web service with your own hand crafted SOAP request. To generate and test your SOAP requests I recommend a handy tool called SOAP UI which will read your WSDL and create a default request for each method saving you a lot of time. All you need to do is fill in the data and submit the request, wheny ou have it working, just paste the request into your CF code and off you go.

<cfsavecontent variable="localscope.soapRequest">
<cfoutput>
<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>
    <MyMethod>
      <userContext xsi:type="ns1:userContext">
        <name xsi:type="xsd:string">USERNAME</name>
        <password xsi:type="xsd:string">PASSWORD</password>
      </userContext>
      <MyItem>
            <userGroup xsi:type="xsd:string" xmlns="">1</userGroup>
            <transactionType xsi:type="xsd:string" xmlns="">New</transactionType>
            <adType xsi:type="xsd:string" xmlns="">L</adType>
            <channel xsi:type="xsd:string" xmlns="">WEB</channel>
      </MyItem>
    </MyMethod>
  </soapenv:Body>
</soapenv:Envelope>
</cfoutput>
</cfsavecontent>
<cfhttp url="webServiceURL?wsdl" method="POST" resolveurl="NO" useragent="Axis/1.1">
<cfhttpparam type="header" name="SOAPAction" value="#WSURL#MyMethod">
<cfhttpparam type="xml" name="body" value="#localscope.soapRequest#">
</cfhttp>
<cfset localscope.soapresponse = XMLParse(cfhttp.FileContent) />

SKY customers beware of scammers

Rogue Traders

How often does a company (such as your bank) call you, and ask you to prove who you are by giving your security password, name, address, DOB etc, but how do you know it is your bank calling and not just a scammer phishing for your details.

Normally I am pretty savvy about this stuff and I never give personal details out over the phone, if someone calls me claiming to be from a company that I do business with and they want to discuss my account or personal details I make them prove who they are or I call the company back on a known number.

 

But alas this week I let my guard slip and I was scammed out of my  debit card details. I have been ill this week, so maybe I just wasn't as with it as I normally am, but either way it just goes to show how easy it is for any of us to fall foul to these evil scammers.

 

Here is what happened.

Read more...

axis error with web services

ColdFusion 2 Comments »

If you get this Axis error like the one below when trying to consume a CFC web service, or even when trying to browse the WSDL with your browser, here are a couple of possible reasons why.

 

  1. You have a default "/" mapping in your cfadmin, this breaks CFC's in general.
  2. You have a mapping with the same name as one the folders in the path to your CFC


Remove said mapping and u should be fine.

 

AXIS error


Sorry, something seems to have gone wrong... here are the details:


Fault - [coldfusion.xml.rpc.SkeletonClassLoader$UnresolvedCFCDataTypeException : Could not resolve CFC datatype: /wallpaper/admin/cfc/test.cfc][; nested exception is:
coldfusion.xml.rpc.CFCInvocationException: [coldfusion.xml.rpc.SkeletonClassLoader$UnresolvedCFCDataTypeException : Could not resolve CFC datatype: /wallpaper/admin/cfc/test.cfc][


AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString: [coldfusion.xml.rpc.SkeletonClassLoader$UnresolvedCFCDataTypeException : Could not resolve CFC datatype: /wallpaper/admin/cfc/test.cfc][; nested exception is:
coldfusion.xml.rpc.CFCInvocationException: [coldfusion.xml.rpc.SkeletonClassLoader$UnresolvedCFCDataTypeException : Could not resolve CFC datatype: /wallpaper/admin/cfc/test.cfc][
faultActor:
faultNode:
faultDetail:

Installing CFX (java) tags

ColdFusion 1 Comment »

I have been having an issue on one of our servers with CFX (java) tag not working.  Basically after installing the tag and adding it via the CFADMIN any use of the tag would just result in a blank page, no errors nothing, the tag simply did not work.

The coldfusion-event.log would contain the following error.

 

java.lang.NoClassDefFoundError: com/allaire/cfx/CustomTag
    at java.lang.ClassLoader.defineClass0(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:282)
    at jrunx.util.JRunURLClassLoader.loadClass(JRunURLClassLoader.java:77)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:282)
    at jrunx.util.JRunURLClassLoader.loadClass(JRunURLClassLoader.java:77)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:282)
    at jrunx.util.JRunURLClassLoader.loadClass(JRunURLClassLoader.java:77)
    at jrunx.util.JRunURLClassLoader.loadClass(JRunURLClassLoader.java:69)
    at coldfusion.bootstrap.BootstrapClassLoader.loadClass(BootstrapClassLoader.java:220)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:219)
    at coldfusion.tagext.CfxTag.doStartTag(CfxTag.java:88)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:1915)
    at cfgoogle2ecfm633585263.runPage(D:\wwwroot\newebia.co.uk\wwwroot\google.cfm:36)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:152)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:349)
    at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:225)
    at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:51)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:69)
    at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:52)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:115)
    at coldfusion.CfmServlet.service(CfmServlet.java:107)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:78)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
    at com.intergral.fusionreactor.filter.FusionReactorFilter.B(Unknown Source)
    at com.intergral.fusionreactor.filter.FusionReactorFilter.A(Unknown Source)
    at com.intergral.fusionreactor.filter.FusionReactorFilter.doFilter(Unknown Source)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
    at jrun.servlet.FilterChain.service(FilterChain.java:101)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:257)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:541)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:204)
    at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:318)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:426)
    at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:264)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
 

 

It turns out that it is required to have the path to the CFX.JAR file in the JVM Classpath in your jvm.config file, at least in my situation. I am not exactly sure why this is required on this particular server, as I have checked on several other servers and they do not have this path. Only one other server had this path and it was listed under the shared libraries path and not the jvm class path.

 

Give it a try, it may work for you also if you are having this problem.

 

open your jvm.config file, and add the following to the end of the JVM CLASS PATH

 

{application.home}/../wwwroot/WEB-INF/lib

 

NOTE: This applies to the standalone install only. If you are running CFMx on top of JRUN or any other J2EE server you will need to modify the paths accoridngly. Just find your CFX.JAR file and create the path to that folder.

 

I also want to mention that the CFMX documentation on adding CFX tags is lousy. If you search online you will mind many different suggestions on how to install a JAVA CFX tag, some will tell you to add the FULL path to the JAR file and put it in the lib folder  (e.g. {application.home}/lib/cfxtag/jar), some will tell you to use a windows filesystem path (e.g. c:\cfusionmx7\cfx\mytag.jar) and a myriad of others.

The method I have always used is to simply put your CFX tags into c:\cfusionmx7\cfx and add "{application.home}/../cfx" to the jvm class path As long a sthere are no other problems, such as the one above, then this should work.

 

Thanks to Mark Drew for helping me solve this. 

 

SQL Server Tips and Tricks

SQL Server No Comments »

Below is my own collection of useful tips for SQL Server 2000. This covers most of the more "not common knowledge" issues I have to deal with quite regulalrly and which you may find yourself having to deal with at least once. I hope you might find this useful.

 

Restoring databases

When restoring a backup database from another server, you will have an orphan user and you need to link the database user to an SQL server login.

The easiest way is to create the original login name on the SQL server, then restore the database backup.

Now run this command against the database from query analyser.

 sp_change_users_login 'auto_fix', 'Login'

 

This will automatically associate the orphaned user with the specified Login.

If you have multiple users in the database that each have their own login, you will need to associate each one like this.

 

sp_change_users_login 'update_one', ‘user', 'Login'

 

This links the specified user in the current database to login. login must already exist. user and login must be specified.

 

Taking a DB offline

 

When taking a DB offline you may need to kill all open connections first, the below stored procedure will allow you to do this. Execute the stored procedure with: 

Exec kill_all "database name"

 


 

------------- copy below this line --------------

CREATE procedure Kill_All  

      @dbname varchar(50) 

as 

Begin 

 -- Declare all the relevant variables

 declare @counter int, 

 @spid int 

 

 -- Temp table to store all the connections

 Create table #StoreConnections 

 ( 

 id int identity(1,1), 

 spid int, 

 kpid int, 

 dbid int 

 ) 

  

 -- Insert all the connection SPIDs ...

 Insert into #StoreConnections 

 Select spid,kpid,dbid from master..sysprocesses where kpid = 0 and dbid = db_id(@dbname) and spid > 40 

 

 Set @counter = 1 

 Set @spid = (Select spid from #StoreConnections where id = @counter) 

 

 -- Start killing all the SPIDs ...    

 While @spid <> ''  

 Begin 

  Select @spid 

  Exec ('Kill ' + @spid) 

  Set @counter = @counter + 1 

  Set @spid = (Select spid from #StoreConnections where id = @counter) 

 End 

 

 -- Cleanup activity. 

 Drop table #StoreConnections 

  

End

--------------- copy above this line ------------

 

Changing Object Ownership

 

When restoring a database backup for a client, often their tables may be owned by the DBO and not their database user.

The script below will change the owner of all tables to the specified 'NewUserName'

 

DECLARE @currentObject nvarchar(517)

DECLARE @qualifiedObject nvarchar(517)

DECLARE @currentOwner varchar(50)

DECLARE @newOwner varchar(50)

 

SET @currentOwner = 'dbo'

SET @newOwner = 'NewUserName'

 

DECLARE alterOwnerCursor CURSOR FOR

SELECT [name] FROM dbo.sysobjects

WHERE xtype = 'U' or xtype = 'P'

AND LEFT([name], 2) <> 'dt'

OPEN alterOwnerCursor

FETCH NEXT FROM alterOwnerCursor INTO @currentObject

WHILE @@FETCH_STATUS = 0

BEGIN

   SET @qualifiedObject = CAST(@currentOwner as varchar) + '.' + CAST(@currentObject as varchar)

   EXEC sp_changeobjectowner @qualifiedObject, @newOwner

   FETCH NEXT FROM alterOwnerCursor INTO @currentObject

END

CLOSE alterOwnerCursor

DEALLOCATE alterOwnerCursor

 

Useful SQL Server Related links


http://www.support.microsoft.com/?id=314546
Moving DB's between Servers

http://www.support.microsoft.com/?id=224071
Moving SQL Server Databases to a New Location with Detach/Attach

http://support.microsoft.com/?id=221465
Using WITH MOVE in a Restore

http://www.support.microsoft.com/?id=246133
How To Transfer Logins and Passwords Between SQL Servers

http://www.support.microsoft.com/?id=298897
Mapping Logins & SIDs after a Restore

http://www.dbmaint.com/SyncSqlLogins.asp
Utility to map logins to users

http://www.support.microsoft.com/?id=168001
User Logon and/or Permission Errors After Restoring Dump

http://www.support.microsoft.com/?id=240872
How to Resolve Permission Issues When a Database Is Moved Between SQL Servers

http://www.sqlservercentral.com/scripts/scriptdetails.asp?scriptid=599
Restoring a .mdf

http://www.support.microsoft.com/?id=307775
Disaster Recovery Articles for SQL Server

http://www.dbmaint.com/SyncSqlLogins.asp

Sync SQL logins

Powered by Mango Blog. Design and Icons by N.Design Studio
RSS Feeds