VCard bug

Hello everyone,

I was retriving VCards just fine with

VCard vcard = new VCard();
vcard.load(connection, jid);

but if the user does not have VCard stored on server, Smack prints in console “No VCard for testbot@jabbim.cz” and then throws a NullPointerException.

As I was looking into source code I found in VCard.java:

private void doLoad(Connection connection, String user) throws XMPPException {
        setType(Type.GET);
        PacketCollector collector = connection.createPacketCollector(
                new PacketIDFilter(getPacketID()));
        connection.sendPacket(this);         VCard result = null;
        try {
            result = (VCard) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());             if (result == null) {
                String errorMessage = "Timeout getting VCard information";
                throw new XMPPException(errorMessage, new XMPPError(
                        XMPPError.Condition.request_timeout, errorMessage));
            }
            if (result.getError() != null) {
                throw new XMPPException(result.getError());
            }
        }
        catch (ClassCastException e) {
            System.out.println("No VCard for " + user);
        }         copyFieldsFrom(result);
    }

The problem is the exception(NullPointerException), which is thrown on the last line. As I see it, “copyFieldsFrom(result);” should be in the try block and no exception will be thrown. Maybe also XMPPException should be thrown from the catch block instead of the System.out to signal no VCard.

Does it make sense?

Best regards

Matus Zamborsky

Could you show us the stacktrace of the NPE? Which Smack version are you using?

I am using the newest release 3.3.0. Ant the stacktrace is here:

No VCard for testbot@jabbim.cz
java.lang.NullPointerException
          at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:54)
          at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
          at java.lang.reflect.Field.get(Field.java:372)
          at com.springsource.loaded.ri.ReflectiveInterceptor.jlrFieldGet(ReflectiveInterceptor.java:1654)
          at org.jivesoftware.smackx.packet.VCard.copyFieldsFrom(VCard.java:603)
          at org.jivesoftware.smackx.packet.VCard.doLoad(VCard.java:587)
          at org.jivesoftware.smackx.packet.VCard.load(VCard.java:561)
          at com.inqool.persistchatbot.service.impl.XMPPServiceImpl.getVCard(XMPPServiceImpl.java:243)
          at com.inqool.persistchatbot.service.impl.RoomServiceImpl.loadNameFromVCard(RoomServiceImpl.java:27)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:601)
          at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
          at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
          at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
          at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
          at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
          at $Proxy54.loadNameFromVCard(Unknown Source)
          at com.inqool.persistchatbot.service.impl.XMPPServiceImpl$1$1$1.doInTransactionWithoutResult(XMPPServiceImpl.java:113)
          at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:33)
          at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
          at com.inqool.persistchatbot.service.impl.XMPPServiceImpl$1$1.presenceChanged(XMPPServiceImpl.java:105)
          at org.jivesoftware.smack.Roster.fireRosterPresenceEvent(Roster.java:666)
          at org.jivesoftware.smack.Roster.access$700(Roster.java:50)
          at org.jivesoftware.smack.Roster$PresencePacketListener.processPacket(Roster.java:727)
          at org.jivesoftware.smack.Connection$ListenerWrapper.notifyListener(Connection.java:853)
          at org.jivesoftware.smack.PacketReader$ListenerNotification.run(PacketReader.java:422)
          at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
          at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
          at java.util.concurrent.FutureTask.run(FutureTask.java:166)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
          at java.lang.Thread.run(Thread.java:722)

SMACK-450