Message Boards
How I can inject dependency of classes in an extension module?
Mark Molina, modified 3 Years ago.
How I can inject dependency of classes in an extension module?
New Member Posts: 11 Join Date: 10/14/11 Recent Posts
Hello, I am developing a new extension for the Login module. I was able to modify the login.jsp page and change some texts (a simple POC) and these changes replaced correctly the original Login page. Problem started when I tried to include more complexity...I want to add to my Login page, all the OpenId providers configured in the portal. As it is are existing modules, I added all the dependencies of the build.gradle file:dependencies {
...
compileOnly 'com.liferay:com.liferay.portal.security.sso.openid.connect.api'
compileOnly 'com.liferay:com.liferay.portal.security.sso.openid.connect.impl'
...
originalModule group: "com.liferay", name: "com.liferay.login.web"
}
After that were included all required jars to my project so there is no depency or compilation problem. Then I was able to include some classes in my new extended LoginPortlet.java.
As documentation explain, I am including the variables with @Reference annotation:
@Reference
private OpenIdConnect _openIdConnect; @Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;I am assuming that code fire Dependency Injection, so it is no needed to instatntiate manually. I am using them as follows:public class LoginPortlet extends MVCPortlet { @Reference(
target = "(&(release.bundle.symbolic.name=com.liferay.login.web)(&(release.schema.version>=1.0.0)(!(release.schema.version>=2.0.0))))",
unbind = "-"
)
protected void setRelease(Release release) {
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
List<IDP> providers = new ArrayList<IDP>();
ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
long companyId = themeDisplay.getCompanyId(); if (_openIdConnect.isEnabled(companyId)) {
Collection<String> idps = _openIdConnectProviderRegistry.getOpenIdConnectProviderNames(companyId);
Iterator<String> iterator = idps.iterator();
while (iterator.hasNext()) {
providers.add(new IDP(iterator.next()));
}
} renderRequest.setAttribute("idps", providers); super.doView(renderRequest, renderResponse);
} @Reference
private OpenIdConnect _openIdConnect; @Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;
}My problem is that at execution time it throws a NPE and I don't know the reason. In fact if I debugg the code, referenced variables _openIdConnect and _openIdConnectProviderRegistry were not autowired.Finally same happens if I try to use any class of the OpenId module in the login.jsp directly.There is anyone can help me please?Regards,Mark
...
compileOnly 'com.liferay:com.liferay.portal.security.sso.openid.connect.api'
compileOnly 'com.liferay:com.liferay.portal.security.sso.openid.connect.impl'
...
originalModule group: "com.liferay", name: "com.liferay.login.web"
}
After that were included all required jars to my project so there is no depency or compilation problem. Then I was able to include some classes in my new extended LoginPortlet.java.
As documentation explain, I am including the variables with @Reference annotation:
@Reference
private OpenIdConnect _openIdConnect; @Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;I am assuming that code fire Dependency Injection, so it is no needed to instatntiate manually. I am using them as follows:public class LoginPortlet extends MVCPortlet { @Reference(
target = "(&(release.bundle.symbolic.name=com.liferay.login.web)(&(release.schema.version>=1.0.0)(!(release.schema.version>=2.0.0))))",
unbind = "-"
)
protected void setRelease(Release release) {
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
List<IDP> providers = new ArrayList<IDP>();
ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
long companyId = themeDisplay.getCompanyId(); if (_openIdConnect.isEnabled(companyId)) {
Collection<String> idps = _openIdConnectProviderRegistry.getOpenIdConnectProviderNames(companyId);
Iterator<String> iterator = idps.iterator();
while (iterator.hasNext()) {
providers.add(new IDP(iterator.next()));
}
} renderRequest.setAttribute("idps", providers); super.doView(renderRequest, renderResponse);
} @Reference
private OpenIdConnect _openIdConnect; @Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;
}My problem is that at execution time it throws a NPE and I don't know the reason. In fact if I debugg the code, referenced variables _openIdConnect and _openIdConnectProviderRegistry were not autowired.Finally same happens if I try to use any class of the OpenId module in the login.jsp directly.There is anyone can help me please?Regards,Mark
David H Nebinger, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
It's missing, but is your LoginPortlet also having an @Component annotation? @Reference only works for @Components.
I'm thinking it's not. An @Component will not start unless all @Reference values are resolvable and wired in. If they were available and you had an @Component, then they would not be null. If they were not available and you had an @Component, then your component would not start. Regardless if they were available or not, if you are not an @Component you class can be instantiated and called and nothing gets "autowired" so the values would be null.
I'm thinking it's not. An @Component will not start unless all @Reference values are resolvable and wired in. If they were available and you had an @Component, then they would not be null. If they were not available and you had an @Component, then your component would not start. Regardless if they were available or not, if you are not an @Component you class can be instantiated and called and nothing gets "autowired" so the values would be null.
Mark Molina, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
New Member Posts: 11 Join Date: 10/14/11 Recent Posts
Hello David, in fact when the new extension files are cloned into my Extension modues I think they are created as a copy of the original ones and includes the @Component annotation.
This is my code for example,
package com.liferay.login.web.internal.portlet;
import com.liferay.login.web.IDP;
import com.liferay.login.web.constants.LoginPortletKeys;
import com.liferay.portal.kernel.model.Release;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.security.sso.openid.connect.OpenIdConnect;
import com.liferay.portal.security.sso.openid.connect.OpenIdConnectProviderRegistry;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.portlet.Portlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Peter Fellwock
*/
@Component(
immediate = true,
property = {
"com.liferay.portlet.add-default-resource=true",
"com.liferay.portlet.css-class-wrapper=portlet-login",
"com.liferay.portlet.display-category=category.tools",
"com.liferay.portlet.icon=/icons/login.png",
"com.liferay.portlet.preferences-owned-by-group=true",
"com.liferay.portlet.private-request-attributes=false",
"com.liferay.portlet.private-session-attributes=false",
"com.liferay.portlet.render-weight=50",
"com.liferay.portlet.single-page-application=false",
"com.liferay.portlet.use-default-template=true",
"javax.portlet.display-name=Sign In",
"javax.portlet.expiration-cache=0",
"javax.portlet.init-param.add-process-action-success-action=false",
"javax.portlet.init-param.config-template=/configuration.jsp",
"javax.portlet.init-param.template-path=/META-INF/resources/",
"javax.portlet.init-param.view-template=/login.jsp",
"javax.portlet.name=" + LoginPortletKeys.LOGIN,
"javax.portlet.portlet-mode=text/html;config",
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=guest,power-user,user"
},
service = Portlet.class
)
public class LoginPortlet extends MVCPortlet {
@Reference(
target = "(&(release.bundle.symbolic.name=com.liferay.login.web)(&(release.schema.version>=1.0.0)(!(release.schema.version>=2.0.0))))",
unbind = "-"
)
protected void setRelease(Release release) {
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
List<IDP> providers = new ArrayList<IDP>();
ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
long companyId = themeDisplay.getCompanyId();
if (_openIdConnect.isEnabled(companyId)) {
Collection<String> idps = _openIdConnectProviderRegistry.getOpenIdConnectProviderNames(companyId);
Iterator<String> iterator = idps.iterator();
while (iterator.hasNext()) {
providers.add(new IDP(iterator.next()));
}
}
renderRequest.setAttribute("idps", providers);
super.doView(renderRequest, renderResponse);
}
@Reference
private OpenIdConnect _openIdConnect;
@Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;
}
Maybe I am missing something?
Thanks for your help.
This is my code for example,
package com.liferay.login.web.internal.portlet;
import com.liferay.login.web.IDP;
import com.liferay.login.web.constants.LoginPortletKeys;
import com.liferay.portal.kernel.model.Release;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.security.sso.openid.connect.OpenIdConnect;
import com.liferay.portal.security.sso.openid.connect.OpenIdConnectProviderRegistry;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.portlet.Portlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Peter Fellwock
*/
@Component(
immediate = true,
property = {
"com.liferay.portlet.add-default-resource=true",
"com.liferay.portlet.css-class-wrapper=portlet-login",
"com.liferay.portlet.display-category=category.tools",
"com.liferay.portlet.icon=/icons/login.png",
"com.liferay.portlet.preferences-owned-by-group=true",
"com.liferay.portlet.private-request-attributes=false",
"com.liferay.portlet.private-session-attributes=false",
"com.liferay.portlet.render-weight=50",
"com.liferay.portlet.single-page-application=false",
"com.liferay.portlet.use-default-template=true",
"javax.portlet.display-name=Sign In",
"javax.portlet.expiration-cache=0",
"javax.portlet.init-param.add-process-action-success-action=false",
"javax.portlet.init-param.config-template=/configuration.jsp",
"javax.portlet.init-param.template-path=/META-INF/resources/",
"javax.portlet.init-param.view-template=/login.jsp",
"javax.portlet.name=" + LoginPortletKeys.LOGIN,
"javax.portlet.portlet-mode=text/html;config",
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=guest,power-user,user"
},
service = Portlet.class
)
public class LoginPortlet extends MVCPortlet {
@Reference(
target = "(&(release.bundle.symbolic.name=com.liferay.login.web)(&(release.schema.version>=1.0.0)(!(release.schema.version>=2.0.0))))",
unbind = "-"
)
protected void setRelease(Release release) {
}
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
List<IDP> providers = new ArrayList<IDP>();
ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
long companyId = themeDisplay.getCompanyId();
if (_openIdConnect.isEnabled(companyId)) {
Collection<String> idps = _openIdConnectProviderRegistry.getOpenIdConnectProviderNames(companyId);
Iterator<String> iterator = idps.iterator();
while (iterator.hasNext()) {
providers.add(new IDP(iterator.next()));
}
}
renderRequest.setAttribute("idps", providers);
super.doView(renderRequest, renderResponse);
}
@Reference
private OpenIdConnect _openIdConnect;
@Reference
private OpenIdConnectProviderRegistry<?, ?> _openIdConnectProviderRegistry;
}
Maybe I am missing something?
Thanks for your help.
Mark Molina, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
New Member Posts: 11 Join Date: 10/14/11 Recent Posts
Additionally, if I test a similar code inside another Portlet Module it works fine. I don't know if it could be related to the fact that extension modules are hooks for existing ones and when they are deployed some initializations or dependency injections don't happens.
David H Nebinger, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
This looks right to me. Have you tried purging osgi/state?
Mark Molina, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
New Member Posts: 11 Join Date: 10/14/11 Recent Posts
Hello David, actually I did, also I had clean all temporary files, etc but same results. Dependency injections are ok in other modules but still failling in EXT. I can´t fin the reason...
Upender Kashyap, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
Junior Member Posts: 30 Join Date: 8/12/20 Recent Posts
Hello Mark, I am facing the same issue.. did u get any solution for this?
Mark Molina, modified 3 Years ago.
RE: How I can inject dependency of classes in an extension module?
New Member Posts: 11 Join Date: 10/14/11 Recent Posts
Hello Upender, unfortunetly nop. If you can fix it please share, please!