You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Muhammad Mohsen <m....@gmail.com> on 2010/10/24 01:29:43 UTC

[T5.2] Beginner questions about modules, services injection and packages

Hello everyone,

I have a couple of questions I believe to be so primitive but I hope you
don't mind answering them :)

1.Services
I understand that sfl4j Logger class and ObjectLocator class are
automatically available for services and they are considered resources.
*http://tapestry.apache.org/tapestry5.2-dev/tapestry-ioc/module.html*<http://tapestry.apache.org/tapestry5.2-dev/tapestry-ioc/module.html>
*, "Caching Services" section.*

What I don't understand is, why when I inject Logger into a component.
(@Inject) or even not using the annotation at all, it's resolves fine. But
when I use it in a service, I have to use @InjectResource ? What are my
options here in bother cases ?
I know that If an interface has a single implemented, I could only declare
an instance of that interface:

private Logger logger;

Even without an annotation nor autobinding.

2.Modules
I simply created a class, suffixed it "Module" so it ended up being named
"DataAccessModule".
I added a
public static void bind(ServiceBinder binder) {
binder.bind(UserDAO.class, UserDAOImpl.class);
}
method just like my AppModule which works perfectly find. When I used the
"DataAccessModule" to bind classes. As I @Inject them. They couldn't be
resolved and I get a "Class not found exception". This module is under the
services package right beside "AppModule.java"
So why aren't my services resolved ?

3.Packages
I understand that the pages packages is for pages, components is for
components, base is basically for interfaces\abstract classes. But what if I
wanted to add some business logic classes. For processing stuff,
opening\closing connections. Classes that are used by services mainly. Where
should I put them ?
Like I did with slf4j Logger interface. It has only one implementer so no
problem should occur and none did. When I just used the interface:

private interface Logger logger;

It was automatically resolved.
So If I want to have my services automatically resolved based on the naming
convention (InterfaceName.class for InterfaceNameImpl.class). Where should I
put the interface and the impl class ?

Please correct me if I mentioned any false information.

Thanks in advance for your time :)

-- 
*Regards,*
*Muhammad Gelbana
Java Software Programmer*

Re: [T5.2] Beginner questions about modules, services injection and packages

Posted by Mark Shead <ma...@xeric.net>.
When you make a droppable jar you usually only have one Module class
specified in the jar file.  If you need more, you  annotate the specified
module to point it to other submodules.  So you should probably be able to
do the same thing for your AppModule to point it to other submodules as
well.  Admittedly I haven't tried this.

The web.xml file has a filter listed for "app".  Tapestry adds Module to the
end of this to decide what module to load.  So it loads AppModule.  You can
change that in web.xml if you like and you may be able to add additional
filters pointing to other modules there as well.

I'm not sure why you'd want to create a separate module as you described.
 The main reason I see for creating different modules is when you need to
bring the app up in a different state.  For example, when you run the app
you might want to have IDataSource bound to LiveDataSource, but when you run
the Selenium tests you want it bound to TestDataSource.  You can accomplish
this by creating a TestModule and then telling the test web.xml to load the
"test" filter instead of the "app".

I don't think it is "wrong" to use separate modules and I doubt you'll see
any performance difference. I'm just not sure how much you will gain by
separating your bindings out into different modules.  If you really need
that level of separation, I'd do it as a separate project and add it in by
referencing the jar. That would give you complete separation. If one
particular concern (Business logic, data access) is generic enough that you
might be able to reuse it elsewhere, you might consider putting it into its
own project where it can be tested and developed separately.

Otherwise, you can probably achieve the same benefits simply by organizing
your bind statements in groups.  So you have one group with all of your DAO
bindings another with all of your business logic services, etc.

Thats my perspective, but it doesn't mean it is the "right" way to do it for
your project.

Mark



On Sun, Oct 24, 2010 at 7:15 AM, Muhammad Mohsen <m....@gmail.com>wrote:

> Thank you Mark,
>
> That explained lots of things :). I want to make a separate module class
> just for the sake of code organization. May be It's wrong to create a
> module
> class for every service category(data access, business logic..etc). What do
> you think ? Is it ok performance and architecture wise ?
>
> I don't know how to specify a module in the web.xml, don't reckon I read
> anything about this !
>
> About the auto loading, I thought it was meant only for the droppable jar
> feature. I think the @Submodule annotation will do the trick.
>
> Thanks a lot for your time :)
>
> On Sun, Oct 24, 2010 at 5:19 AM, Mark <ma...@xeric.net> wrote:
>
> > On Sat, Oct 23, 2010 at 6:29 PM, Muhammad Mohsen <m.gelbana@gmail.com
> > >wrote:
> >
> > >
> > > 2.Modules
> > > I simply created a class, suffixed it "Module" so it ended up being
> named
> > > "DataAccessModule".
> > > I added a
> > > public static void bind(ServiceBinder binder) {
> > > binder.bind(UserDAO.class, UserDAOImpl.class);
> > > }
> > > method just like my AppModule which works perfectly find. When I used
> the
> > > "DataAccessModule" to bind classes. As I @Inject them. They couldn't be
> > > resolved and I get a "Class not found exception". This module is under
> > the
> > > services package right beside "AppModule.java"
> > > So why aren't my services resolved ?
> >
> >
> > I think you want to put:
> >  binder.bind(UserDAO.class, UserDAOImpl.class);
> > in your AppModule file instead of creating a new DataAccessModule for it.
> > You can bind a bunch of different things just by adding them to the list.
> > If
> > you take a look at your web.xml file you'll see there is a filter set to
> > "app" and that is going to load the AppModule.
> >
> > If you are wanting it to be separate in order to create a drop in
> > autoloading module, you need to check out the documents on creating
> > autoloading modules.
> > http://people.apache.org/~uli/tapestry-site/ioc-autoload.html
> >
> >  If you want to have a separate module for DataAccess, you might be able
> to
> > add it to the web.xml or possibly use the @SubModule annotation (see the
> > section about IOC Autoloading).
> >
> > If you have an interface and its implementation that you want to load
> with
> > the binder.bind command, I think you'd usually put them in the services
> > package, but don't think it matters because you are going to explicitly
> > tell
> > Tapestry where to find them when you call bind in your AppModule file.
> >
> > Mark
> >
>
>
>
> --
> *Regards,*
> *Muhammad Gelbana
> Java Software Programmer*
>

Re: [T5.2] Beginner questions about modules, services injection and packages

Posted by Muhammad Mohsen <m....@gmail.com>.
Thank you Mark,

That explained lots of things :). I want to make a separate module class
just for the sake of code organization. May be It's wrong to create a module
class for every service category(data access, business logic..etc). What do
you think ? Is it ok performance and architecture wise ?

I don't know how to specify a module in the web.xml, don't reckon I read
anything about this !

About the auto loading, I thought it was meant only for the droppable jar
feature. I think the @Submodule annotation will do the trick.

Thanks a lot for your time :)

On Sun, Oct 24, 2010 at 5:19 AM, Mark <ma...@xeric.net> wrote:

> On Sat, Oct 23, 2010 at 6:29 PM, Muhammad Mohsen <m.gelbana@gmail.com
> >wrote:
>
> >
> > 2.Modules
> > I simply created a class, suffixed it "Module" so it ended up being named
> > "DataAccessModule".
> > I added a
> > public static void bind(ServiceBinder binder) {
> > binder.bind(UserDAO.class, UserDAOImpl.class);
> > }
> > method just like my AppModule which works perfectly find. When I used the
> > "DataAccessModule" to bind classes. As I @Inject them. They couldn't be
> > resolved and I get a "Class not found exception". This module is under
> the
> > services package right beside "AppModule.java"
> > So why aren't my services resolved ?
>
>
> I think you want to put:
>  binder.bind(UserDAO.class, UserDAOImpl.class);
> in your AppModule file instead of creating a new DataAccessModule for it.
> You can bind a bunch of different things just by adding them to the list.
> If
> you take a look at your web.xml file you'll see there is a filter set to
> "app" and that is going to load the AppModule.
>
> If you are wanting it to be separate in order to create a drop in
> autoloading module, you need to check out the documents on creating
> autoloading modules.
> http://people.apache.org/~uli/tapestry-site/ioc-autoload.html
>
>  If you want to have a separate module for DataAccess, you might be able to
> add it to the web.xml or possibly use the @SubModule annotation (see the
> section about IOC Autoloading).
>
> If you have an interface and its implementation that you want to load with
> the binder.bind command, I think you'd usually put them in the services
> package, but don't think it matters because you are going to explicitly
> tell
> Tapestry where to find them when you call bind in your AppModule file.
>
> Mark
>



-- 
*Regards,*
*Muhammad Gelbana
Java Software Programmer*

Re: [T5.2] Beginner questions about modules, services injection and packages

Posted by Mark <ma...@xeric.net>.
On Sat, Oct 23, 2010 at 6:29 PM, Muhammad Mohsen <m....@gmail.com>wrote:

>
> 2.Modules
> I simply created a class, suffixed it "Module" so it ended up being named
> "DataAccessModule".
> I added a
> public static void bind(ServiceBinder binder) {
> binder.bind(UserDAO.class, UserDAOImpl.class);
> }
> method just like my AppModule which works perfectly find. When I used the
> "DataAccessModule" to bind classes. As I @Inject them. They couldn't be
> resolved and I get a "Class not found exception". This module is under the
> services package right beside "AppModule.java"
> So why aren't my services resolved ?


I think you want to put:
 binder.bind(UserDAO.class, UserDAOImpl.class);
in your AppModule file instead of creating a new DataAccessModule for it.
You can bind a bunch of different things just by adding them to the list. If
you take a look at your web.xml file you'll see there is a filter set to
"app" and that is going to load the AppModule.

If you are wanting it to be separate in order to create a drop in
autoloading module, you need to check out the documents on creating
autoloading modules.
http://people.apache.org/~uli/tapestry-site/ioc-autoload.html

 If you want to have a separate module for DataAccess, you might be able to
add it to the web.xml or possibly use the @SubModule annotation (see the
section about IOC Autoloading).

If you have an interface and its implementation that you want to load with
the binder.bind command, I think you'd usually put them in the services
package, but don't think it matters because you are going to explicitly tell
Tapestry where to find them when you call bind in your AppModule file.

Mark