RE: Liferay Guestbook Web Application - entryLocalService cannot be resolve

thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
I'm following the Guestbook tutorial in https://portal.liferay.dev

I think that  the 7.1 tutorial Liferay Guestbook Web Application is wrong.

After developed the services including Guestbook and Entity entities I wrote the custom service methods.

But exactly following the Liferay's tutorials, I get an error in GuestbookLocalServiceImpl telling me that I can't use methods from Entity's services.

I can't use the entryLocalService object and I get the "entryLocalService cannot be resolved" error.
entryLocalService.getEntries() ---> error

But of course I can use the EntryLocalServiceUtil methods:
EntryLocalServiceUtil.getEntries() ---> OK

I'm brand new to OSGi development and very probable I'm missing something from build.gradle dependencies:
dependencies {
    compileOnly group: "com.liferay", name: "com.liferay.petra.lang"
    compileOnly group: "com.liferay", name: "com.liferay.petra.string"
    compileOnly group: "com.liferay", name: "com.liferay.portal.aop.api"
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
    compileOnly group: "org.osgi", name: "org.osgi.annotation.versioning"
    compileOnly group: "org.osgi", name: "org.osgi.core"
    compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations"
    compileOnly project(":modules:guestbook:guestbook-api")
}
buildService {
    apiDir = "../guestbook-api/src/main/java"
}
group = "mc.infocomm.ipl.test.guestbook"
Please anyone can help me ?
Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
How did you include the Entry service in your Guestbook layer? Via the <reference /> tag in the Guestbook's <entity />?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David, thank you for your reply.
I just tried to add the below in service.xml:
<reference entity="Entry" package-path="mc.infocomm.ipl.test.guestbook" />
The builService Gradle task ends without errors:
> Task :modules:guestbook:guestbook-service:buildService
Building Entry
Building Guestbook
Writing ..\guestbook-api\src\main\java\mc\infocomm\ipl\test\guestbook\service\GuestbookLocalService.java
Writing ..\guestbook-api\src\main\java\mc\infocomm\ipl\test\guestbook\service\GuestbookLocalServiceUtil.java
Writing ..\guestbook-api\src\main\java\mc\infocomm\ipl\test\guestbook\service\GuestbookLocalServiceWrapper.java
Writing src\main\resources\service.properties
but still the Entry's methods remain unresolved.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
In your GuestbookLocalServiceImpl, you should be able to use autocomplete to find an instance of entryLocalService that is available from a superclass...

It is via this entryLocalService that you get access to the Entry services.
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,
You was so gentle to address me to the problem.
But still I'm in trouble because do a Ctrl-space for autocomplete but I get the list of EntryLocalService* classes and also the assetEntryLocalService but no entryLocalService methods.
For example in the code I can see userLocalService.getUser() method in blue color but  entryLocalService methods are unusable.
I think that beside autocomplete there is something missing in the tutorial about to reference the Entry methods from inside the Guestbook services.
Thank you in advance for some more helps.
Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Well, it absolutely works, I've done it before.

And now that I think about it, the <reference /> tag isn't necessary either, ServiceBuilder should auto-inject all of the entity local service and persistence objects for all entities in the service.xml file.

Are you sure you're not looking at "entryLocalService" and may in fact be looking at "entryService", the remote service for Entries? The remote service always starts out with no methods, so it kind of sounds like this might be playing a role?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,
I removed the <reference /> tag from the service.xml file.

The below is the class code:

public Guestbook deleteGuestbook(long guestbookId, ServiceContext serviceContext) throws PortalException, SystemException {
    
            Guestbook guestbook = getGuestbook(guestbookId);
        
            List<Entry> entries = entryLocalService.getEntries(serviceContext.getScopeGroupId(), guestbookId);    // entryLocalService cannot be resolved
        
            for (Entry entry : entries) {
                    entryLocalService.deleteEntry(entry.getEntryId());    // entryLocalService cannot be resolved
            }
        
            guestbook = deleteGuestbook(guestbook);
    
        return guestbook;
        
        }

The below is the build.grade in the guestbook-service module:

dependencies {
    compileOnly group: "com.liferay", name: "com.liferay.petra.lang"
    compileOnly group: "com.liferay", name: "com.liferay.petra.string"
    compileOnly group: "com.liferay", name: "com.liferay.portal.aop.api"
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
    compileOnly group: "org.osgi", name: "org.osgi.annotation.versioning"
    compileOnly group: "org.osgi", name: "org.osgi.core"
    compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations"
    compileOnly project(":modules:guestbook:guestbook-api")
}
buildService {
    apiDir = "../guestbook-api/src/main/java"
}
group = "mc.infocomm.ipl.test.guestbook"


Please could you help me more ?
Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
That is the exact chunk of code and it should work, but it's failing for you?

Did you rebuild services after changing the service.xml and the classes?

How is the failure manifesting itself? Is it just the IDE reporting errors or did you actually try deploying the code?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Yes I rebuilt the services.
There are errors in IDE and the container doesn't activate the guestbook-service module cause the compile errors
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Okay, so when you try to start the bundle in gogo, what is reported?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,

I'm deployng the test modules in Eclipse IDE - attached here you can see the error mark of guestbook-service in Servers panel of the IDE.
Maibe I have to delete the project and restart from scratch but I'm a bit worried since this big issue in a so simple module.

Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
A red X doesn't do anything to diagnose the issue...

Can you get into the Gogo shell (telnet localhost 11311 if on 7.0 or use the Gogo control panel in 7.1+), use the lb command to find the service, then start XXX to start the bean w/ the matching id?

That will give you the detailed OSGi reason why the bundle cannot start. It's from that point that we'll diagnose and resolve the issue.
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,
After I dragged the guestbook-api and guestbook-service from the Project Explorer to the running Tomcat bundle, only guestbook-api is present in the lb command output in the Gogo shell:

2150|Active | 1|guestbook-api (1.0.0)|1.0.0

So I can't try to start guestbook-service because it is not present.

Thank you for your support !

Ivano
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Okay, let's try something different.

If you open a command prompt in the guestbook-service module and attempt to build it, what is the generated output?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,

I executed the gradlew.bat buildService command from the root of the project.
I'm not able to tun Gradle commands from other folders. I'm using only the Gradle wrapped in the IDE.
Below what I done and no errors building services:

C:\dev\liferay\7.2.0-ce-ga1\ipl-workspace\mc-infocomm-ipl>gradlew.bat buildService
> Task :modules:guestbook:guestbook-service:buildService
Building Entry
Building Guestbook
Writing src\main\resources\service.properties
BUILD SUCCESSFUL in 4s
1 actionable task: 1 executed
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
So it builds the services fine, how about just a complete build using "gradlew.bat build" and let it churn it all?

You should be able to run gradlew in subdirs, but you'll have to use a relative path to get there, i.e. within the guestbook-service module it would be "..\..\..\gradlew.bat build".
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David, here is the output from the complete build using "gradlew.bat build" within the guestbook-service module:

C:\dev\liferay\7.2.0-ce-ga1\ipl-workspace\mc-infocomm-ipl\modules\guestbook\guestbook-service>..\..\..\gradlew.bat build
Starting a Gradle Daemon, 3 incompatible and 1 stopped Daemons could not be reused, use --status for details> Task :modules:guestbook:guestbook-service:compileJava
C:\dev\liferay\7.2.0-ce-ga1\ipl-workspace\mc-infocomm-ipl\modules\guestbook\guestbook-service\src\main\java\mc\infocomm\ipl\test\guestbook\service\impl\GuestbookLocalServiceImpl.java:117: error: cannot find symbol
                    List<Entry> entries = entryLocalService.getEntries(serviceContext.getScopeGroupId(), guestbookId);  // entryLocalService cannot be resolved
                                          ^
  symbol:   variable entryLocalService
  location: class GuestbookLocalServiceImpl
C:\dev\liferay\7.2.0-ce-ga1\ipl-workspace\mc-infocomm-ipl\modules\guestbook\guestbook-service\src\main\java\mc\infocomm\ipl\test\guestbook\service\impl\GuestbookLocalServiceImpl.java:120: error: cannot find symbol
                            entryLocalService.deleteEntry(entry.getEntryId());  // entryLocalService cannot be resolved
                            ^
  symbol:   variable entryLocalService
  location: class GuestbookLocalServiceImpl
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors> Task :modules:guestbook:guestbook-service:compileJava FAILEDFAILURE: Build failed with an exception.* What went wrong:
Execution failed for task ':modules:guestbook:guestbook-service:compileJava'.
> Compilation failed; see the compiler error output for details.* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 11s
3 actionable tasks: 1 executed, 2 up-to-date
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Hmm, wicked.

So I can see from the buildService output there is an Entry entity, so I'm also assuming you have an EntryLocalServiceImpl class, etc., in the mc.infocomm.ipl.test.guestbook.service.impl package?
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,


Of course there is an EntryLocalServiceImpl class in the mc.infocomm.ipl.test.guestbook.service.impl package.

It is the one with inside the Entry's methods  that are not found from the GuestbookLocalServiceImpl class.
I can't call the methods entryLocalService.getEntries() and entryLocalService.deleteEntry().

Here is the code:

package mc.infocomm.ipl.test.guestbook.service.impl;import com.liferay.portal.aop.AopService;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.Validator;import java.util.Date;
import java.util.List;import mc.infocomm.ipl.test.guestbook.model.Entry;
import mc.infocomm.ipl.test.guestbook.service.base.EntryLocalServiceBaseImpl;
import mc.infocomm.ipl.test.guestbook.exception.EntryEmailException;
import mc.infocomm.ipl.test.guestbook.exception.EntryMessageException;
import mc.infocomm.ipl.test.guestbook.exception.EntryNameException;import org.osgi.service.component.annotations.Component;/**
 * The implementation of the entry local service.
 *
 * <p>
 * All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the <code>mc.infocomm.ipl.test.guestbook.service.EntryLocalService</code> interface.
 *
 * <p>
 * This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
 * </p>
 *
 * @author icarrara
 * @see EntryLocalServiceBaseImpl
 */
@Component(
    property = "model.class.name=mc.infocomm.ipl.test.guestbook.model.Entry",
    service = AopService.class
)
public class EntryLocalServiceImpl extends EntryLocalServiceBaseImpl {    /*
     * NOTE FOR DEVELOPERS:
     *
     * Never reference this class directly. Use <code>mc.infocomm.ipl.test.guestbook.service.EntryLocalService</code> via injection or a <code>org.osgi.util.tracker.ServiceTracker</code> or use <code>mc.infocomm.ipl.test.guestbook.service.EntryLocalServiceUtil</code>.
     */
    
    public Entry addEntry(long userId, long guestbookId, String name, String email, String message, ServiceContext serviceContext) throws PortalException {            long groupId = serviceContext.getScopeGroupId();            User user = userLocalService.getUserById(userId);            Date now = new Date();            validate(name, email, message);            long entryId = counterLocalService.increment();            Entry entry = entryPersistence.create(entryId);            entry.setUuid(serviceContext.getUuid());
            entry.setUserId(userId);
            entry.setGroupId(groupId);
            entry.setCompanyId(user.getCompanyId());
            entry.setUserName(user.getFullName());
            entry.setCreateDate(serviceContext.getCreateDate(now));
            entry.setModifiedDate(serviceContext.getModifiedDate(now));
            entry.setExpandoBridgeAttributes(serviceContext);
            entry.setGuestbookId(guestbookId);
            entry.setName(name);
            entry.setEmail(email);
            entry.setMessage(message);            entryPersistence.update(entry);            return entry;
            
        }
    
    
        public Entry updateEntry (long userId, long guestbookId, long entryId, String name, String email, String message, ServiceContext serviceContext) throws PortalException, SystemException {
    
                Date now = new Date();
    
                validate(name, email, message);
    
                Entry entry = getEntry(entryId);
    
                User user = userLocalService.getUserById(userId);
    
                entry.setUserId(userId);
                entry.setUserName(user.getFullName());
                entry.setModifiedDate(serviceContext.getModifiedDate(now));
                entry.setName(name);
                entry.setEmail(email);
                entry.setMessage(message);
                entry.setExpandoBridgeAttributes(serviceContext);
    
                entryPersistence.update(entry);
    
                return entry;
                
            }
        
        
            public Entry deleteEntry (long entryId, ServiceContext serviceContext) throws PortalException {
    
                Entry entry = getEntry(entryId);                entry = deleteEntry(entryId);                return entry;
                    
            }
            
            
            public List<Entry> getEntries(long groupId, long guestbookId) {
                
                return entryPersistence.findByG_G(groupId, guestbookId);
                
            }            
            public List<Entry> getEntries(long groupId, long guestbookId, int start, int end) throws SystemException {                return entryPersistence.findByG_G(groupId, guestbookId, start, end);
                
            }            
            public List<Entry> getEntries(
                    
                long groupId, long guestbookId, int start, int end, OrderByComparator<Entry> obc) {                return entryPersistence.findByG_G(groupId, guestbookId, start, end, obc);
                
            }            
            public int getEntriesCount(long groupId, long guestbookId) {
                
                return entryPersistence.countByG_G(groupId, guestbookId);
                
            }
            
    
            protected void validate(String name, String email, String entry) throws PortalException {                if (Validator.isNull(name)) {
                    
                    throw new EntryNameException();
                    
                }                if (!Validator.isEmailAddress(email)) {
                    
                    throw new EntryEmailException();
                    
                }                if (Validator.isNull(entry)) {
                    
                    throw new EntryMessageException();
                    
                }
                    
            }
    
    }
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Ah, I have an inkling having seen the 7.2 syntax...

Can you try adding the following to your bnd.bnd file in the guestbook-service module:

-dsannotations-options: inherit
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Okay, Ivano, I have to start with an apology...

I was assuming that the long-standing practice of Service Builder injecting local service and persistence automatically in the XXXLocalServiceImpl's super class would obviously not have been stripped, even for 7.2.

But in discussions w/ other Liferay folks I've learned that actually has happened. Other local services and persistence instances for entities in the same service.xml file are no longer automatically injected.

Mostly this was due to the conversion of the local services into pure OSGi components and the issues that would have sprung from having circular references on all of the local service implementations (if Guestbook @References the Entry local service and Entry @References the Guestbook local service, neither one can be resolved by OSGi since all references are not ready for injection).

Instead, that whole practice has been scrapped.

Going forward, if you need other local service or persistence instances for the other entities, you need to manually declare the member variables yourself and @Reference inject them. Note, however, that by doing this yourself it doesn't eliminate the potential of creating a circular reference in your components that would prevent them from starting.

I'm going to hook up w/ the documentation team and other folks involved to get clarification about how developers should proceed and certainly update the doco to represent these new developer responsibilities.

I'm just sorry it took this long to develop the proper answer for you...
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,

No apologies from you, you are teaching me many new things.

Thank you for your last reply about the @Reference annotation.
Unfortunately I can't understand where I have to put the above annotation.

Also I read your Blog article here  https://liferay.dev/blogs/-/blogs/liferay-osgi-annotations-what-they-are-and-when-to-use-them   but still I'm not able to call methods in EntryLocalServiceImpl class from the GuestbookLocalServiceImpl class in my Guestbook application in 7.2 environment.

Please could you address me where I have to put the @Reference annotation in my services ?

Thank you in advance,
Ivano C.
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David, probably I solved my case :-)

I added the below code in the GuestbookLocalServiceImpl class:

@Reference(unbind = "-")
        protected void setEntryService(EntryLocalService entryLocalService) {
            _entryLocalService = entryLocalService;
        }        private EntryLocalService _entryLocalService;

Then I changed the calls to the methods provided by the EntryLocalServiceImpl class, for example:

List<Entry> entries = _entryLocalService.getEntries(serviceContext.getScopeGroupId(), guestbookId);    // NO MORE ERRORS !!!

It is the above the right solution ?

Thank you,
Ivvano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Yep, that's spot on...

Alternatively, you could set the dependency injector back to spring to make things work the way they used to.

I wrote up a blog about SB 7.2 changes, some of which I learned about when helping here: https://liferay.dev/blogs/-/blogs/important-7-2-service-builder-changes
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Ok, I added  "dependency-injector='spring'" in the service.xml file.

After I removed the below code in the GuestbookLocalServiceImpl class:

@Reference(unbind = "-")
        protected void setEntryService(EntryLocalService entryLocalService) {
            _entryLocalService = entryLocalService;
        }       
private EntryLocalService _entryLocalService;


Then I changed the calls to the methods provided by the EntryLocalServiceImpl class, for example:

List<Entry> entries = entryLocalService.getEntries(serviceContext.getScopeGroupId(), guestbookId);    // NO MORE ERRORS !!!

But at that point I get a lot of errors in the service packages saying:  "The import com.liferay.portal.spring cannot be resolved".


I solved the issue adding the below in the build.gradle:

compile 'com.liferay:com.liferay.portal.spring.extender:2.0.15'.


BUT now in the IDE when I drag the guestbook-service module in the Tomcat bundle the module doesn't start and is marked with a red point.

If I do a deploy Gradle task I get the below error log:

Gradle Tasks: deploy> Task :modules:guestbook:guestbook-api:compileJava UP-TO-DATE
> Task :modules:guestbook:guestbook-api:buildCSS NO-SOURCE
> Task :modules:guestbook:guestbook-api:processResources NO-SOURCE
> Task :modules:guestbook:guestbook-api:transpileJS SKIPPED
> Task :modules:guestbook:guestbook-api:configJSModules SKIPPED
> Task :modules:guestbook:guestbook-api:replaceSoyTranslation NO-SOURCE
> Task :modules:guestbook:guestbook-api:wrapSoyAlloyTemplate SKIPPED
> Task :modules:guestbook:guestbook-api:classes UP-TO-DATE
> Task :modules:guestbook:guestbook-api:jar UP-TO-DATE
> Task :modules:guestbook:guestbook-service:compileJava UP-TO-DATE
> Task :modules:guestbook:guestbook-service:buildCSS NO-SOURCE
> Task :modules:guestbook:guestbook-service:processResources UP-TO-DATE
> Task :modules:guestbook:guestbook-service:transpileJS SKIPPED
> Task :modules:guestbook:guestbook-service:configJSModules SKIPPED
> Task :modules:guestbook:guestbook-service:replaceSoyTranslation NO-SOURCE
> Task :modules:guestbook:guestbook-service:wrapSoyAlloyTemplate SKIPPED
> Task :modules:guestbook:guestbook-service:classes UP-TO-DATE> Task :modules:guestbook:guestbook-service:jar FAILED
error  : Class mc.infocomm.ipl.test.guestbook.service.impl.EntryLocalServiceImpl is not assignable to specified service com.liferay.portal.aop.AopService
error  : Class mc.infocomm.ipl.test.guestbook.service.impl.EntryServiceImpl is not assignable to specified service com.liferay.portal.aop.AopService
error  : Class mc.infocomm.ipl.test.guestbook.service.impl.GuestbookLocalServiceImpl is not assignable to specified service com.liferay.portal.aop.AopService
error  : Class mc.infocomm.ipl.test.guestbook.service.impl.GuestbookServiceImpl is not assignable to specified service com.liferay.portal.aop.AopServiceFAILURE: Build failed with an exception.* What went wrong:
Execution failed for task ':modules:guestbook:guestbook-service:jar'.
> Bundle mc.infocomm.ipl.test.guestbook.service-1.0.0.jar has errors

At this point I'm a bit worried about the absence of a some sort of guideline about dependencies to develop in 7.x versions.


Thank you in advance for any other help,
Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
It wouldn't surprise me if the environment is now confused, first version of API was based on OSGi, this one based on Spring...

I would recommend purging Guestbook from the env completely (make sure there is nothing in osgi/modules, work, etc) as well as purging osgi/state.

Also, for spring DI none of your classes should be declared as @Components. You'll want to purge all of these annotations. It may be necessary, although I admit I don't know, to try purging all of the generated SB code and then re-gen again, as this would help to eliminate any possible code hanging around that was based off of the other dependency injector.

This kind of cleanup has never been easy in SB, relatively simple things like changing package name in the service.xml would often leave cruft hanging behind... It just takes a little bit of patience to work through it...
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,


Thank you very much for your efforts during the development of this thread.


In fact other than resolve the issue, you teached me a lot of things and helped me to follow my learning curve.


Contrarily to your final advise in the final chapter "Choosing The Right Dependency Injector" in the  https://liferay.dev/blogs/-/blogs/important-7-2-service-builder-changes  Blog article, I decided to use the new default in Service Builder that is dependency-injector="ds"


The above cause starting a new project based on 7.2 I think that if Liferay made the choice of the above as the new Service Builder default, it can be a better guarantee of continuity for the future.


Best regards and thank you again for your help!
Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
You're welcome, Ivano.

I think choosing the right dependency-injector is going to be a personal choice. I also don't believe it has to be a "forever" choice; I think it is perfectly acceptable to choose "spring" for one SB implementation and "ds" for another. Use the one that best fits what you are building.

Me, most of the time I tend to see all of my entities in the service.xml as "tightly coupled", such as the guestbook and entry entities. Since they are coupled, for me at least, I feel like guestbook methods (like the delete example) will be invoking entry methods and entry methods will at times want to invoke guestbook methods (i.e. if guestbook had a "last entry timestamp" that was updated every time an entry were being added). Because I see these kinds of relationships as being a "default state" for the entities, I want them to establish and use the services and persistence layers of others and I wouldn't want to have to figure out how to work around circular dependencies, etc. So for me, a "spring" dependency injector is typically going to be the right choice because of how I see the entities relating.

The DS option is definitely easier when your service components need to access other DS components beyond the local service.xml services, so if I knew I had to go down that road, DS would probably be my choice.

I don't think there's ever going to be a "right" vs "wrong" answer, you can make both options fit in pretty much every case you find.

I wrote the blog, though, because I really wasn't aware of these changes for 7.2, and it wouldn't surprise me if others who had been doing Liferay for a while didn't know about them either. Yours is the second error about the new 7.2 implementation I've encountered, so I wanted to make sense out of what was going on and spell everything out to avoid future devs from stumbling into the same situation.
thumbnail
Ivano Carrara, modified 6 Years ago. Expert Posts: 350 Join Date: 7/3/05 Recent Posts
Dear David,

One more question ...
Since I decided to use the  dependency-injector="ds", now I have a doubt.
In a previous message you wrote: "Also, for spring DI none of your classes should be declared as @Components. You'll want to purge all of these annotations."
When I ran Service Builder the first time, with the dependency-injector="ds" as default, it generated the below code in the skeleton of all *LocalServiceImpl classes:

@Component(
    property = "model.class.name=mc.infocomm.ipl.test.guestbook.model.Guestbook",
    service = AopService.class
)
public class GuestbookLocalServiceImpl extends GuestbookLocalServiceBaseImpl {
}

So now I have to remove the above code from all  *LocalServiceImpl classes ?

Please note that actually the Guestbook portlet including the @Component annotations in all  *LocalServiceImpl classes is running very well and without errors.

Thank you again for clarifications and help.

Ivano C.
thumbnail
David H Nebinger, modified 6 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Sorry for the confusion, Ivano.

If you are using "spring" for the dependency injector, then your local service impl classes should not have the @Component annotation nor @Reference injection inside of the class. The local service impl will be a Spring bean, not a DS component.

If you are using "ds" for the dependency injector, then your local service impl classes must have the @Component annotation in order to be exposed as a DS component and are free to use @Reference injection.

The bodies of the local service impl class shouldn't change much between the two dependency injectors; if you have an addGuestbook(...) method, it would apply to both forms so you don't need to strip it out when switching.

The thing to remember is that historically Service Builder has been really bad at cleaning up after itself. I don't know that SB can clean up correctly when you switch the dependency injector after you have built the services the first time. My guess is it doesn't know how to clean up at all, leaving you the developer with the responsibility to perform the necessary cleanup.