views:

63

answers:

5

Hello,

I'm trying to set up a Spring configuration with tutorials and some stuff. It seems everything is OK but when I call the constructor of a Bean with a @Resource everything blows up.

I'm am also giving a try to Apache Click killing two birds with one stone.

Please, can anyone tell me what happens here and how could I fix this?

Thank you.

The error:

Caused by: java.lang.RuntimeException: No Context available on ThreadLocal Context Stack
at org.apache.click.Context$ContextStack.peek(Context.java:934)
at org.apache.click.Context$ContextStack.access$000(Context.java:885)
at org.apache.click.Context.getThreadLocalContext(Context.java:168)
at org.apache.click.extras.control.MenuFactory.loadFromMenuXml(MenuFactory.java:495)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:302)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:255)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:197)
at org.test.pages.BasePage.<init>(BasePage.java:15)
at org.test.pages.HomePage.<init>(HomePage.java:24)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 30 more

This is my applicationContext.xml:

<context:annotation-config />

<context:component-scan base-package="org.test" />
<tx:annotation-driven />

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.OracleDriver" />
    <property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.10:1521:xe" />
    <property name="user" value="HR" />
    <property name="password" value="hr"/>

</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="ctest" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
            <property name="showSql" value="true" />
        </bean>
    </property>

</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

This is my web.xml:

    <display-name>CTest</display-name>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>ClickServlet</servlet-name>
    <servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>ClickServlet</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.htm</welcome-file>
</welcome-file-list>

+2  A: 

This sounds completely unrelated to Spring, as your stacktrace shows the exception coming from org.apache.click classes.

What does org.test.pages.BasePage do?

I'd suggest trimming down your code to something simple like outputting "Hello World" to test the Spring configuration and context, and then adding other libraries you'd like to use in your webapp.

matt b
+2  A: 

This doesn't really have anything to do with Spring. Your HomePage class is calling a method on a Click API which it apparently isn't allowed to do.

I suggest you not try to kill two birds with one stone. It's hard enough learning one framework at a time without trying to learn two at the same time, since you'll forever be trying to figure out what's going wrong.

I suggest taking Spring out of the equation, and get yourself comfortable with Click first. Or vice versa.

skaffman
That code without Spring works perfectly :/
Khanser
+2  A: 

Click Framework docs suggest to use scope = "prototype" for pages. If you use annotation-based configuration, it will be:

@Component @Scope("prototype")
axtavt
A: 

Edit: I changed the code as suggested but my dao is still null. Also at the appContext I put:

<context:component-scan base-package="org.test.pages" scope-resolver="org.apache.click.extras.spring.PageScopeResolver"/>

Ok, I tried to inject my Dao in my IndexPage but in the constructor cTestDao is null.
What am i doing wrong?

Thanks

IndexPage class code:

@Component @Scope("prototype")
public class IndexPage extends Page {

    @Resource
    protected CTestDao<Employee> cTestDao;

 public IndexPage(){
     super();
     List<Employee> list = cTestDao.getBeans(Employee.class);
     for(Employee e:list){
      String s = String.format("Name:%1 Last Name:%2 Salary%3€",e.getFirstName(),e.getLastName(),e.getSalary());
      System.out.println(s);
     }
 }
}
Khanser
+1  A: 

Hi,

It seems as if you want to treat Click pages like Spring beans, in other words you want Spring to create your Click page and inject the dependencies. Spring supports two types of dependency injection: through setter methods and constructor. In your example above you are accessing the dao in your Page constructor, but the dao can only be injected after the page has been constructed.

I suggest you move your code into the Page onInit() method.

Alternatively you could inject the DAO into the Page constructor "IndexPage(CTestDao dao)", but I haven't tested whether that will work or not.

Kind regards

Bob

Bob Schellink
It seems my Class needed the interface InitializingBean so i could place there the initializations i had on my constructor.Thanks everyone!
Khanser