jueves, 21 de noviembre de 2013

"An invalid security token was provided..." invoking CXF Web Services

Error:  An invalid security token was provided (An error happened processing a Username Token "{0}")

Complete SOAP fault response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">ns1:InvalidSecurityToken</faultcode>
      <faultstring>An invalid security token was provided (An error happened processing a Username Token "{0}")</faultstring>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

There are lots of  reasons which can cause this error. As stated by the message, there's a problem in the security token included in the SOAP request.

In my case, the Web service client was not sending the Type attribute for the Password element of the UsernameToken's Security element.

The error was introduced after upgrading the used CXF version (from an very old version to 2.6.1). The underlying project which implements WS Security in CXF is WSS4J. CXF 2.6.1 ships WSS4J 1.6.6. WSS4J 1.6 enforces compliance to the Basic Security Profile 1.1 (BSP) specification by default. The older CXF version shipped an older WSS4J version which did not enforce compliance to the BSP spec.

It seems the Type attribute for the password element is optional in WS-Security but mandatory in the BSP spec.

In this case we choosed not to demand the clients to include the attribute but to configure the service to not to be compliant with the BSP spec. We use Spring configuration for CXF; this can be easily done in the XML configuration file:

<jaxws:inInterceptors>
    <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <constructor-arg>
            <map>
                 ...
                 <entry key="isBSPCompliant" value="false"/>  
                 ...
            </map>
        </constructor-arg>
    </bean>
</jaxws:inInterceptors&gt

This error also usually happens with the EncodingType attribute.

This conversation proposes an alternative configuration parameter: ws-security.is-bsp-compliant.

References:

miércoles, 9 de octubre de 2013

ArrayIndexOutOfBoundsException deploying app in Weblogic 12c

I'm getting the following exception deploying an app in Weblogic 12c:

java.lang.ArrayIndexOutOfBoundsException: 242890
at com.bea.objectweb.asm.ClassReader.(Unknown Source)
at com.bea.objectweb.asm.ClassReader.(Unknown Source)
at weblogic.application.utils.annotation.ClassInfoImpl.(ClassInfoImpl.java:44)
at weblogic.application.utils.annotation.ClassfinderClassInfos.polulateOneClassInfo(ClassfinderClassInfos.java:145)
at weblogic.application.utils.annotation.ClassfinderClassInfos.populateClassInfos(ClassfinderClassInfos.java:137)
Truncated. see log file for complete stacktrace

As indicated in this stackoverflow entry, a good way to diagnose the error is to "add an exception breakpoint on java.lang.ArrayIndexOutOfBoundsException, then trying to examine the context to find out the parameters".

You can do this clicking the exception in the Console view.




Once you press OK, an exception breakpoint should appear in the Breakpoints view of the Debug perspective.


You can then restart the server in debug mode and try the deployment again. Once you do it, the server should stop execution and start debugging when the exception is throwed.


If you click the source attribute of the ClassInfoImpl class present in the stack, you can see the Jar which contains the offending class.


If you click the jarEntry attribute you can know the offending class.


You can check the class is indeed invalid, through a decompiler, for example:










lunes, 26 de agosto de 2013

BEA-001153 using non-transactional AQ backed MDB in Weblogic

I started receiving the following warning in the Weblogic log after changing the transactionality of an AQ backed MDB:

BEA-001153: Forcibly releasing inactive/harvested connection "weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection@4a8025" back into the data source connection pool "jdbc/XYZ", currently reserved by: java.lang.Exception

The complete stack trace is (BEA-001153):

Forcibly releasing inactive/harvested connection "weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection@4a8025" back into the data source connection pool "jdbc/XYZ", currently reserved by: java.lang.Exception
        at weblogic.jdbc.common.internal.ConnectionEnv.setup(ConnectionEnv.java:352)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:364)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:330)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:487)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:380)
        at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:132)
        at weblogic.jdbc.common.internal.RmiDataSource.getPoolConnection(RmiDataSource.java:474)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:558)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:518)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:511)
        at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:566)
        at oracle.jms.AQjmsConnection.setExceptionListener(AQjmsConnection.java:418)
        at weblogic.ejb.container.internal.JMSConnectionPoller.setUpQueueSessions(JMSConnectionPoller.java:1712)
        at weblogic.ejb.container.internal.JMSConnectionPoller.createJMSConnection(JMSConnectionPoller.java:2298)
        at weblogic.ejb.container.internal.JMSConnectionPoller.connect(JMSConnectionPoller.java:808)
        at weblogic.ejb.container.internal.MDConnectionManager.timerExpired(MDConnectionManager.java:177)
        at weblogic.timers.internal.TimerImpl.run(TimerImpl.java:293)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:545)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

Although this is a very well known exception, it is easier to deal with it when you're working with plain JDBC or in scenarios when you have more control of the underlying connection; but in my case, the connection administration code is provided from server managed components (Foreign Server, JMS Module, destination and connection factory, MDB, etc.).

Before start receiving the warnings, the MDB was using container managed transactionality. Now is using the following attributes (non-transactional):

@TransactionManagement(TransactionManagementType.BEAN)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

After doing some research ([1], [2]), I found that when a Weblogic MDB has Bean managed or NOT_SUPPORTED transaction type, then two dedicated connections are reserved for that MDB:
Looking at the stack trace, it is reasonable to think the warning corresponds to the "AQ JMS Exception Listener" connection (and not to the polling one). Looking at the documentation, you can see the default ping frequency for the periodical exception listener database ping es 2 minutes (Setting the Ping Period for the Exception Listener). So, this connection is idle during 2 minutes each time.

Casually, in my environment, the underlying JDBC data source (jdbc/XYZ: the one you specify in the datasource JNDI Property of the Foreign Server) had a "Inactive Connection Timeout" value of 60 seconds.

Hence, having these simultaneous settings, has to be the reason the warning is being generated (the underlying data source checks for idle connection more often that the Exception Listener connection gets busy):

Data Source "Inactive Connection Timeout" = 60 (seconds) < MDB Exception Listener connection "ping period" = 120 (seconds)

After increasing the Data Source "Inactive Connection Timeout", the warning stopped appearing.

It would be better to reduce the Exception Listener "ping period" value, but I haven't find a way to do it (neither in the JMS Module, Foreign Server, Destination, Connection Factory or MDB).

References:


jueves, 15 de agosto de 2013

Inspecting Weblogic classloaders (without using ws-cat)

I know Weblogic have a great application called ws-cat that you can use to diagnose classloading problems in the deployed applications. But, sometimes a find myself needing "a little more". I've had the necessity of knowing the classloaders involved in the classloader hierarchy and the classpath for each one...even if I know this is unsupported, that some of the involved classloaders have no documented behaviour,..etc.

I started with a typical EAR/WAR packaged Web application with a servlet, containing some code like this:

ClassLoader cl = this.getClass().getClassLoader();
while(cl != null) {
  System.out.println("Cl: " + cl + ", class: " + cl.getClass());
  cl = cl.getParent();
}

Invoking the servlet, I obtained this:

Cl: weblogic.utils.classloaders.ChangeAwareClassLoader@22dd997d finder: weblogic.utils.classloaders.CodeGenClassFinder@704fd3b4 annotation: TestClApp@TestClWeb, class: class weblogic.utils.classloaders.ChangeAwareClassLoader
Cl: weblogic.utils.classloaders.FilteringClassLoader@8d40807 finder: weblogic.utils.classloaders.CodeGenClassFinder@185b0818 annotation: TestClApp@TestClWeb, class: class weblogic.utils.classloaders.FilteringClassLoader
Cl: weblogic.utils.classloaders.GenericClassLoader@b39c954 finder: weblogic.utils.classloaders.CodeGenClassFinder@706c26 annotation: TestClApp@, class: class weblogic.utils.classloaders.GenericClassLoader
Cl: weblogic.utils.classloaders.FilteringClassLoader@54cc3303 finder: weblogic.utils.classloaders.CodeGenClassFinder@2a293573 annotation: , class: class weblogic.utils.classloaders.FilteringClassLoader
Cl: weblogic.utils.classloaders.GenericClassLoader@1f0fde7d finder: weblogic.utils.classloaders.CodeGenClassFinder@1db2cc30 annotation: , class: class weblogic.utils.classloaders.GenericClassLoader
Cl: sun.misc.Launcher$AppClassLoader@752a2259, class: class sun.misc.Launcher$AppClassLoader
Cl: sun.misc.Launcher$ExtClassLoader@21353d27, class: class sun.misc.Launcher$ExtClassLoader

Thus, the classloader hierarchy in my webapp is: ChangeAwareClassLoader -> FilteringClassLoader -> GenericClassLoader -> FilteringClassLoader -> GenericClassLoader -> AppClassLoader (JVM) -> ExtClassLoader (JVM).

But now I want to know if I can obtain some information from them. Using a little reflection, we can see the methods the classloaders offer us:

ClassLoader cl = this.getClass().getClassLoader();

while(cl != null) {
  System.out.println("Cl: " + cl + ", class: " + cl.getClass());
  if(cl.getClass().getName().contains("ChangeAwareClassLoader") || 
     cl.getClass().getName().contains("FilteringClassLoader") ||
     cl.getClass().getName().contains("GenericClassLoader")) {

    System.out.println("Methods:");
    Method[] methods = cl.getClass().getMethods();
    for(Method method : methods) {
   System.out.println("- " + method);
}
  }
  
  cl = cl.getParent();
}

Observing the output, yo can see all of the involved Weblogic classloaders offer the following method:

public java.lang.String weblogic.utils.classloaders.ChangeAwareClassLoader.getClassPath()

You can use again some reflection to invoke that method. If you do it, you can find the method returns the classpath for the classloader, with each entry separated by ';' (in Windows?). So, doing something like this, yo can obtain the classloader classpath.

ClassLoader cl = this.getClass().getClassLoader();
while(cl != null) {
  System.out.println("Cl: " + cl + ", class: " + cl.getClass());
  
  if(cl.getClass().getName().contains("ChangeAwareClassLoader") || 
     cl.getClass().getName().contains("FilteringClassLoader") ||
     cl.getClass().getName().contains("GenericClassLoader")) {
 
    System.out.println("Classpath:");
    Method method = cl.getClass().getMethod("getClassPath");
String classpath[] = ((String)method.invoke(cl)).split(";");
for(String cpEntry : classpath) {
  System.out.println(cpEntry);
}
  }
  
  cl = cl.getParent();
}

That gives us very cool information about our application runtime. For example we can check if the documentation is telling us the truth :P, which classloaders have the web module classes, which have the EJB module classes, which have the App-level classes, etc. It can be even more useful if you're using shared libraries and want to know what's really going on.

In my tests I used

ClassLoader cl = this.getClass().getClassLoader();

but maybe is more useful to use:

ClassLoader cl = Thread.currentThread().getContextClassLoader();

Luckily, for my scenario, the results are exactly the same.

As I said at the post start, you may not use the output of this code as a "source of truth", but just as a means to get more light in your diagnosing efforts. This is internal Weblogic material that I guess "we should not use". For example, each of the Weblogic classloaders, has a companion "finder" classloader with its own classpath; what does it does?

method = cl.getClass().getMethod("getFinderClassPath");
classpath = ((String)method.invoke(cl)).split(";");
for(String cpEntry : classpath) {
  System.out.println(cpEntry);
}



martes, 13 de agosto de 2013

"Connection refused" debugging Weblogic using Eclipse OEPE

Error in Eclipse OEPE: Failed to connect to remote VM. Connection refused. Connection refused: connect.


In this case, the cause was my local development server was configured to run in production mode. In this mode, the debug options are not included in the start order.


One way to fix it is look for the PRODUCTION_MODE variable setting that is causing the server to start in that mode. In my case that variable was set in the setDomainEnv script to true. Fix:




miércoles, 24 de julio de 2013

Installation of WebLogic 10.3.6 standalone with ADF 11gR2


  1. Install WebLogic 10.3.6 with ADF 11gR1 11.1.1.6.0.
  2. Install patches to upgrade ADF to 11gR2 11.1.2.2.0 (or 11.1.2.3.0, 11.1.2.4.0, etc.).
    • Installation guide (My Oracle Support): How To Install the ADF Runtime Libraries 11g Release 2 in WebLogic Sever 10.3.5 10.3.6 (Doc ID 1328698.1).
    • Download page: My Oracle Support.

domingo, 7 de julio de 2013

Formatting the current date in Oracle OSB's XQuery

There's  no  format-dateTime() in Oracle OSB's XQuery implementation (as of 11.1.1.7). So I had to come up with something like this  :-S :

declare function xf:current-formatted-dateTime()
    as xs:string {
    let $currentDate := fn:current-date()
    let $currentTime := fn:current-time() (: no seconds-from-dateTime() :-( :)
    let $year := fn:year-from-date($currentDate)
let $month := fn:month-from-date($currentDate)
let $day := fn:day-from-date($currentDate)
let $hours := fn:hours-from-time($currentTime)
let $minutes := fn:minutes-from-time($currentTime)
let $seconds := fn:seconds-from-time($currentTime)
let $monthZeroPadded :=
if($month < 10) then xs:string(concat('0', $month))
else xs:string($month)
let $dayZeroPadded :=
if($day < 10) then xs:string(concat('0', $day))
else xs:string($day)
let $hoursZeroPadded :=
if($hours < 10) then xs:string(concat('0', $hours))
else xs:string($hours)
let $minutesZeroPadded :=
if($minutes < 10) then xs:string(concat('0', $minutes))
else xs:string($minutes)
let $secondsNoMS := xs:integer(fn:substring-before(xs:string($seconds), '.'))
let $secondsNoMSZeroPadded :=
if($secondsNoMS < 10) then xs:string(concat('0', $secondsNoMS))
else xs:string($secondsNoMS)

return concat($year, '-', $monthZeroPadded, '-', $dayZeroPadded, ' ', $hoursZeroPadded, ':', $minutesZeroPadded, ':', $secondsNoMSZeroPadded)
};

It can be placed and  used this way:


Produces this kind of output: 2013-07-07 17:38:05

Here you can find a list of the supported OSB's XQuery functions: http://www.tomecode.com/download/OSB_11g_XQueryFunction_list.txt


jueves, 20 de junio de 2013

OutOfMemoryError in JDeveloper 11.1.1.7 after opening SVN versioned projects

Due to being involved in a SOA Suite 11g project, I'm working on JDeveloper 11g (11.1.1.7). I'm not using the SVN related funcionality of JDeveloper (I try to always use the Eclipse SVN plugin, even if I'm not developing in Eclipse). After opening a SVN versioned project in JDeveloper I checked out with Eclipse, I couldn't work anymore due to OutOfMemoryError errors. Soon after I open JDeveloper, I get the following message:


I tried to increase the heap memory through the ide/bin/ide.conf file (AddVMOption -Xmx1024M) but I noticed that either the IDE was being very memory hungry o was suffering from a  memory leak.


I was not disposed to assign the IDE a big memory quantity so, due to the presence of lots of SVN related classes in the stack trace, I disabled that funcionality: Versioning - Configure - uncheck Versioning Support for Subversion 11.1.1.7....


After disabling it, I could work again.




viernes, 5 de abril de 2013

Choosing the compiler to use in CXF's DynamicClientFactory


  • -Dorg.apache.cxf.common.util.Compiler-fork=true: use javac.
  • -Dorg.apache.cxf.common.util.Compiler-fork=asdfasdfafd or nothing: use Java 6 compiler API.




lunes, 25 de febrero de 2013

Configuring Subversion (SVN) in IBM Integration Designer (IID, formerly WID) 8


I just used the "normal" steps I'd use for installing Subversion support in Eclipse Helios (3.6) which is the underlying Eclipse which Websphere Integration Developer (WID) 8 is based on.

SVN Team Provider:
  • Help  Install new software  Available software sites ▶ download.eclipse.org/releases/helios ▶ Work with  Helios  type filter text: svn  check: Subversive SVN Team Provider  Next  Next ▶ Accept, Finish ▶ Restart Now
SVN Connector:
  • Open perspectve  Other  SVN Repository Exploring  "Subversive Connector Discovery" should automatically appear  SVN Kit 1.3.5  Finish  Next...  Finish ...  Warning: OK  Restart Now
Now you can open SVN Repository Exploring Perspective and start adding repositories.

sábado, 16 de febrero de 2013

Configuración del Softphone (teléfono VoIP) de Une en iPad, iPhone o Android

Para usar el softphone (teléfono VoIP) de Une en iPad (o iPhone) se puede usar la siguiente app: Media5-fone SIP VoIP Mobile Softphone. Una vez instalada, para configurarla, debes disponer solo de tu número telefónico de VoIP y tu contraseña. Suponiendo que te asignaron el número 1234567, la configuración sería la siguiente:

Title: (cualquiera, por ejemplo Une)
Username: 1234567
Password: (tu password)
Servers:

  • SIP Server/Domain/Realm
    • Address: une.net.co
    • Port: 5060 (por defecto)
  • Outbound proxy:
    • Enable Proxy: (si, activar)
    • Address: epmvoip1.une.net.co
    • Port: 5060 (por defecto)
    • Remove Route header: (si, activar)
  • Advanced:
    • Display name: 1234567
    • Auth. Name: toip1234567

Y listo.

Ejemplo:



Para Android, se puede usar la misma aplicación: Media5-fone. Los pasos son muy similares:







Ver también Configuración alternativa del Softphone (teléfono VoIP) de Une en Windows 7 (64 bits).

viernes, 8 de febrero de 2013

Example of JAX-WS handler for accesing WS-Security UsernameToken info

//I really need to configure syntax highlighting and formatting again in my blog :(


package test;

import java.util.Iterator;
import java.util.Set;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;

public class XSecurityJaxWsHandler implements SOAPHandler {

private class Credentials {
public String username = null;
public String password = null;
}

public Set getHeaders() {
return null;
}

public void close(MessageContext arg0) {
}

public boolean handleFault(SOAPMessageContext arg0) {
return true;
}

public boolean handleMessage(SOAPMessageContext messagecontext) {

Boolean outbound = (Boolean)messagecontext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (!outbound) {
try {
SOAPMessage message = messagecontext.getMessage();
SOAPHeader header = message.getSOAPHeader();

Credentials credentials = null;

           if (header != null) {
            credentials = extractCredentialsFromSOAPHeader(header);
           } else {
    generateSOAPFault("No se recibieron credenciales de autenticaci\u00F3n (elemento UsernameToken en SOAP header");
    return false;
           }
           
//do something with sec info...
           
} catch (SOAPException e) {
    generateSOAPFault(e.getMessage());
    e.printStackTrace();
    return false;
    }
}

return true;
}

private void generateSOAPFault(String reason) {
try {
SOAPMessage msg = MessageFactory.newInstance().createMessage();
SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString(reason);
throw new SOAPFaultException(soapFault); 
        }
        catch(SOAPException e) { 
        // uh?
        }
    }

private Credentials extractCredentialsFromSOAPHeader(SOAPHeader header) {
Credentials credentials = new Credentials();
    Iterator headersIt = header.getChildElements();
    while (headersIt.hasNext()) { //...
    Object nextHeader = headersIt.next();
    if(nextHeader instanceof SOAPHeaderElement) {
    SOAPHeaderElement soapHeader = (SOAPHeaderElement)nextHeader;
    if(soapHeader.getLocalName().equals("Security")) { //... (any version)
        Iterator secIt = soapHeader.getChildElements();
        while (secIt.hasNext()) {
        Object nextSecurityElement = secIt.next();
        if(nextSecurityElement instanceof SOAPElement) {
        SOAPElement securitySoapElement = (SOAPElement)nextSecurityElement;
        if(securitySoapElement.getLocalName().equals("UsernameToken")) { //...
        Iterator untSecIt = securitySoapElement.getChildElements();
        while (untSecIt.hasNext()) {
        Object nextUsernameTokenElement = untSecIt.next();
        if(nextUsernameTokenElement instanceof SOAPElement) {
        SOAPElement usernameTokenSoapChildElement = (SOAPElement)nextUsernameTokenElement;
        if(usernameTokenSoapChildElement.getLocalName().equals("Username")) { //...
        credentials.username = usernameTokenSoapChildElement.getFirstChild().getTextContent();
        } else if(usernameTokenSoapChildElement.getLocalName().equals("Password")) { //...
        credentials.password = usernameTokenSoapChildElement.getFirstChild().getTextContent();
        }
        }
        }
        }
        }
        }
    }
    }
    }
return credentials;
}

}

sábado, 26 de enero de 2013

Viaje a Cabo de la Vela y Punta Gallinas (Guajira Colombia)

Tour con salida desde Rioacha hasta Cabo de la Vela o Punta Gallinas:

  • Cabo de la Vela Tour's:


Hospedaje en Punta Gallinas (el mismo que me tocó con Cabo de la Vela Tour's).

  • Hospedaje Alexandra: