Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
traditional jee deployment for liferay 7
i don't want to start a new debate about "is OSGI the right approach" like https://web.liferay.com/de/community/forums/-/message_boards/message/71530222.
There are several reasons, why i have to use a traditional jee deployment:
- use existing processes for deployment to your application server.
deployment piples (e.g. with jenkins), rolling update strategies, cluster deployments,...- use features of your application server.
You can use features of your application server. In case of wildfly (10/11) you can use all JEE 7 features. For example: EJB, JPA, JTA.- use "infrastructure" of your application server
an application server provides useful "infrastructure". For example caches, connection pools, logging, Messaging Queues.- use monitoring of your application server
you can monitor your applications with the capabilities of your application server. For example: request count, max request time, average request time,
There are other people having similar problems, eg. https://web.liferay.com/de/community/forums/-/message_boards/view_message/94484732. Because of that i decided to write things down and share them on github, have a look at:
https://github.com/daniel-niklas/liferay-jee-deploy
- what do you think about this approach?
- is this possible in future Liferay versions?
Best regards
Daniel
use features of your application server.
You can use features of your application server. In case of wildfly (10/11) you can use all JEE 7 features. For example: EJB, JPA, JTA.
What problems are you having for using EJB, JPA, etc?
use "infrastructure" of your application server
an application server provides useful "infrastructure". For example caches, connection pools, logging, Messaging Queues.
Same as previous question. Right now I don't see why of any of these features wouldn' t be usable from Liferay 7.
use monitoring of your application server
you can monitor your applications with the capabilities of your application server. For example: request count, max request time, average request time,
Yes, this can be a problem if you want to have different counters for each "classic" WAR.
What problems are you having for using EJB, JPA, etc?
For example you have one EJB and want to inject this into your JSF managed bean:
@Stateless
public class MyService {
@PersistenceContext(unitName = "myJpaPU")
private EntityManager em;
// ...
}
@ManagedBean
@RequestScoped
public class MyJsfBean {
@EJB
private MyService myService;
// ...
}
When Liferay starts start your "module" as OSGI-WAB, then the application server does not know this deployment. Therefore you can't use this EJB.
Same as previous question. Right now I don't see why of any of these features wouldn' t be usable from Liferay 7.
Currently JCache ist not available in JEE 7. So i use the cache from wildfly. This is infinispan.
For example like so:
//...
import org.infinispan.Cache;
import org.infinispan.manager.CacheContainer;
@Stateless
public class MyService {
@Resource(name = "myCacheContainer")
private CacheContainer cacheContainer;
private Cache<string, adresse> adresseCache;
@PostConstruct
public void postConstruct() {
adresseCache = cacheContainer.getCache("adresseCache");
}
//...
}</string,>
Yes, this can be a problem if you want to have different counters for each "classic" WAR.
Right, the specific monitoring-data for each deployment are missing, because the application server doesn't know them.
All these examples cannot be achieve with OSGI-Deployments.
Please check out this post on Tobias's original thread: https://web.liferay.com/community/forums/-/message_boards/message/104382443. It may be helpful for your use case as well.
- Kyle
i don't think, that this helps. The application server must be responsible for scanning classes etc. In my understanding this is the wrong way round.
Daniel
would have been nice, if you had added a comment to my question about your approach.
If I understand your repository correctly, you did nothing to access the OSGI bundles / classes from your portlet? It does only contain a simple example portlet? In that case you could add this use case as another checkpoint to your todo list.
i'm not sure, if i get us right. What is your use case?
You can for example user UserLocalServiceUtil. This class is provided from portal-kernel.jar.
you can access all classes from portal-kernel without knowing your github - page.
My use case is to have access to classes that are located in the Liferay OSGI bundles from my portlet WAR.
For example DDMTemplateLocalServiceUtil, which was part of portal-kernel until Liferay 6.2, is now located in the OSGI-Bundle com.liferay.dynamic.data.mapping.api. To access that util class I can't put the bundle into my WAR. I need to access the class from the OSGI class loader, as only that one can access the service.
I had to write a WildFly module which modifies the WAR class loader and is very project specific. I hope you find a solution which is more "versatile".
For example DDMTemplateLocalServiceUtil, which was part of portal-kernel until Liferay 6.2, is now located in the OSGI-Bundle com.liferay.dynamic.data.mapping.api. To access that util class I can't put the bundle into my WAR. I need to access the class from the OSGI class loader, as only that one can access the service.
ah ok, i get it. I didn't realize yet, that many Local-Services aren't part of portal-kernel.jar in Lifery 7. In my understanding (in Liferay 6.2) the Interfaces are Part of the shared library, but the implementation und the excecution is part of a webapp. For your example ( com.liferay.dynamic.data.mapping.api) the implementation is part of ROOT.war).
Isn't it the mechanmism of Local-Services?
So hopefully you only need access to the interfaces, the portal-kernal.jar contains the "client stuff".
I had to write a WildFly module which modifies the WAR class loader and is very project specific. I hope you find a solution which is more "versatile".
Can you share your code to get an idea of your approach?
But com.liferay.dynamic.data.mapping.api was never part of ROOT.war (even in Liferay 6.2). DDMTemplateLocalServiceUtil was part of another package in portal-kernel.jar, which is now removed in Liferay 7.
As far as I understand the idea behind OSGI in Liferay 7 and upcoming versions is to down strip ROOT.war and portal-kernel.jar and move nearly all functionality to OSGI bundles - to have a more modular and flexible Liferay architecture, in contrast to the old "monolithic" approach.
I've got no problem with that - as long as my portlets may still be located in a WAR which is able to use nearly all functionality provided by the JEE container as well - what was the intention of my original post.
I would like to pick this topic up since I am about to make migration plans for Liferay 7.
I have a couple of productive portles using some J2EE technologies and now I found myself confronted with
a series of NullPointerExceptions.
My @Stateless and @Statefull beans don't get initialized the @Postcontruct methods don't run and there is no EntityManager by using @PersistenceContext.
Is it really necessary to hack the entire system, as Daniel did or are you guys planning to support this in the future?
best regards
Martin
Hi Daniel,
did you get CDI running with your solution?
I tried adding the WeldCrossContextFilter but it does not work.
Getting the typical exception:
Caused by: java.lang.IllegalStateException: Singleton not set
for STATIC_INSTANCE => []<br> at
org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider$RegistrySingleton.get(RegistrySingletonProvider.java:28)<br>
at
org.jboss.weld.Container.instance(Container.java:55)<br>
at org.jboss.as.weld.WeldProvider.getCDI(WeldProvider.java:61)<br>
at
javax.enterprise.inject.spi.CDI.current(CDI.java:60)<br>
at
org.jboss.weld.servlet.WeldInitialListener.contextInitialized(WeldInitialListener.java:94)<br>
at
org.jboss.weld.servlet.api.helpers.ForwardingServletListener.contextInitialized(ForwardingServletListener.java:34)<br>
at
org.jboss.weld.environment.servlet.EnhancedListener.onStartup(EnhancedListener.java:65)<br>
at
io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:184)<br>
... 8 more
[EDIT]
The solution was to add the Weld Subsystem in standalone.xml or run
the standalone-full.xml profile.
When I installed the
jsf-cdi-applicant sample portlet via Liferay's Osgi method, CDI
functionality worked without having this subsystem enabled, but for
the J2EE deployment I had to enable it.
It was also necessary to
but the Weld-Listener and WeldCrossContextFilter into the web.xml.
Powered by Liferay™