【问题标题】:Spring Social Twitter - NPE when dereferencing Twitter objectSpring Social Twitter - 取消引用 Twitter 对象时的 NPE
【发布时间】:2013-11-26 13:01:28
【问题描述】:

我使用 Spring Social Twitter v. 1.1.0.M4。我成功地启用了与 Twitter 的内存连接。现在我正在尝试保持连接。我的数据库连接和日志记录似乎工作正常,因为用户已通过身份验证,我可以看到他们的 Twitter 登录信息。问题是,我无法访问他们的任何详细信息(花呢,跟随等)。我在控制器中显示用户推文的代码是:

@Autowired
private Twitter twitter;

@Autowired
private TwitterConnectionUtils twitterConnectionUtils;

@Autowired
private SessionBean sessionBean;

@RequestMapping("/")
public String index(Model model) {
    logger.warning("index");
    model.addAttribute("sessionBean", sessionBean);
    List<Tweet> tweets = new ArrayList<Tweet>();

    try {
        if (!twitterConnectionUtils.isConnectedToTwitter()) {
            return "index";
        }
        tweets.addAll(twitter.timelineOperations().getHomeTimeline());
    } catch (Exception e) {
        logger.warning(ExceptionUtils.getStackTrace(e));
        model.addAttribute("exception", e.toString());
        return "index";
    }

    model.addAttribute("tweets", tweets);
    return "twitter/tweets";
}

tweets.addAll(twitter.timelineOperations().getHomeTimeline()); 行中抛出异常。 twitter 不为空,但同时我不能调用任何方法(例如toString),因为我立即得到 NPE。这是logger.warning(ExceptionUtils.getStackTrace(e));中得到的错误的stacktrace:

WARNING: java.lang.NullPointerException
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:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy16.timelineOperations(Unknown Source)
at agh.sr.tweedle.controller.TweetsController.index(TweetsController.java:43)
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:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

任何想法可能导致问题?我还包括我的库的 javaconfig,以供参考:

@Configuration
@EnableTwitter(appId="myAppId", appSecret="myAppSecret")
public class TwitterConfig {

    @Autowired
    private TwitterConnectInterceptor twitterConnectInterceptor;

    @Inject
    private DataSource dataSource;

    @Inject
    private Environment environment;

    @Bean
    public UserIdSource userIdSource() {
        return new UserIdSource() {         
            @Override
            public String getUserId() {
                return "myTestingPurposesLogin"; // TODO change to security-obtained user login
            }
        };
    }

    @Bean
    public ConnectController connectController() {
        CustomConnectController connectionController = 
                new CustomConnectController(connectionFactoryLocator(), connectionRepository());
        connectionController.addInterceptor(twitterConnectInterceptor);
        return connectionController;
    }

    @Bean
    public ConnectionFactoryLocator connectionFactoryLocator() {
        ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();

        registry.addConnectionFactory(new TwitterConnectionFactory(
                "myAppId", "myAppSecret"));

        return registry;
    }

    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    public ConnectionRepository connectionRepository() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
        }
        return usersConnectionRepository().createConnectionRepository(authentication.getName());
    }

    @Bean
    public UsersConnectionRepository usersConnectionRepository() {
        return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator(), 
            textEncryptor());
    }

    @Bean
    public TextEncryptor textEncryptor() {
        return Encryptors.noOpText();
    }

}

【问题讨论】:

  • 您有任何自定义方面吗?做任何 AOP?
  • 不,我没有明确地执行任何 AOP。

标签: java spring twitter spring-social-twitter


【解决方案1】:

改变

tweets.addAll(twitter.timelineOperations().getHomeTimeline());

类似于(伪代码,我不知道返回的所有类型):

var timelineOperations = twitter.TimelineOperations();
var homeTimeline = timelineOperations.GetHomeTimeline();
tweets.addAll(homeTimeline);

这会告诉你哪个方法调用没有返回一个对象。

【讨论】:

  • 这些都不是null(技术上是可能的)。问题出在某个方面。
  • 不,您可以使用带有代理的 AOP 将建议应用于某些连接点。在处理过程中它失败了。
  • 罗伯特,您的代码将在第一行抛出异常。正如我所说,任何对 twitter 的取消引用都会在某些内部代理中导致 NPE。
【解决方案2】:

好吧,我做错了!这是一个易于理解的工作示例:

@Configuration
@EnableTwitter(appId="myAppId", appSecret="myAppSecret")
@EnableJdbcConnectionRepository
public class TwitterConfig {

    @Autowired
    private TwitterConnectInterceptor twitterConnectInterceptor;

    @Bean
    public UserIdSource userIdSource() {
        return new UserIdSource() {         
            @Override
            public String getUserId() {
                return "myTestingPurposesLogin";
            }
        };
    }

    @Bean
    public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
        CustomConnectController connectionController = new CustomConnectController(connectionFactoryLocator, connectionRepository);
        connectionController.addInterceptor(twitterConnectInterceptor);
            return connectionController;
    }

    @Bean
    public TextEncryptor textEncryptor() {
        return Encryptors.noOpText();
    }

}

@EnableJdbcConnectionRepository 注释对于让我走上正轨至关重要。

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 2015-10-19
    • 2015-03-21
    • 2023-02-09
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    相关资源
    最近更新 更多