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
RE: LDAP Import Isuue.
Hi Team,
I have written custom code for LDAP user import. This code works fine on all servers, but I am facing an issue on the production server. Please check the log error image below. If anyone can help us, it would be appreciated.
custom code :
package utils.ldapsync.service;
import com.liferay.portal.kernel.log.Log;
import
com.liferay.portal.kernel.log.LogFactoryUtil;
import
com.liferay.portal.kernel.model.User;
import
com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import
com.liferay.portal.kernel.security.ldap.LDAPSettingsUtil;
import
com.liferay.portal.kernel.service.UserLocalServiceUtil;
import
com.liferay.portal.kernel.util.PrefsPropsUtil;
import
com.liferay.portal.kernel.util.Validator;
import
com.liferay.portal.security.ldap.SafeLdapContext;
import
com.liferay.portal.security.ldap.SafePortalLDAP;
import
com.liferay.portal.security.ldap.configuration.ConfigurationProvider;
import
com.liferay.portal.security.ldap.configuration.LDAPServerConfiguration;
import
com.liferay.portal.security.ldap.exportimport.LDAPToPortalConverter;
import com.liferay.portal.security.ldap.exportimport.LDAPUser;
import com.liferay.portal.security.ldap.exportimport.LDAPUserImporter;
import
com.liferay.portal.security.ldap.exportimport.configuration.LDAPImportConfiguration;
import com.liferay.portal.security.ldap.util.LDAPUtil;
import
com.youngsoft.utils.ldapsync.constants.LDAPConstants;
import
org.osgi.framework.FrameworkUtil;
import
org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.*;
import javax.naming.NamingEnumeration;
import
javax.naming.directory.Attribute;
import
javax.naming.directory.Attributes;
import
javax.naming.directory.SearchControls;
import
javax.naming.directory.SearchResult;
import
java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Component(
immediate = true,
property =
{"service.ranking:Integer=100"},
service =
LDAPUserImporter.class
)
public class
CustomLDAPUserImporterImpl implements LDAPUserImporter {
private static final Log _log = LogFactoryUtil.getLog(CustomLDAPUserImporterImpl.class);
@Reference(
target =
"(factoryPid=com.liferay.portal.security.ldap.configuration.LDAPServerConfiguration)"
)
private
ConfigurationProvider<LDAPServerConfiguration> _ldapServerConfigurationProvider;
@Reference
private volatile LDAPUserImporter _defaultLDAPUserImporter;
@Reference(
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY
)
private volatile SafePortalLDAP _safePortalLDAP;
private LDAPUserImporter getDefaultLDAPUserImporter() {
if (_defaultLDAPUserImporter == null) {
ServiceReference<LDAPUserImporter> serviceReference =
FrameworkUtil.getBundle(getClass()).getBundleContext()
.getServiceReference(LDAPUserImporter.class);
_defaultLDAPUserImporter =
FrameworkUtil.getBundle(getClass())
.getBundleContext()
.getService(serviceReference);
}
return
_defaultLDAPUserImporter;
}
@Override
public User importUser(long ldapServerId, long
companyId, SafeLdapContext safeLdapContext, Attributes attributes,
String password) throws Exception {
_log.info("Entering importUser with SafeLdapContext");
_log.debug("LDAP Server ID: " + ldapServerId + ",
Company ID: " + companyId);
User user =
getDefaultLDAPUserImporter().importUser(ldapServerId, companyId,
safeLdapContext, attributes, password);
if (user != null)
{
_log.info("User imported successfully: " +
user.getFullName());
} else {
_log.warn("User import returned null.");
}
_log.info("Exiting importUser with
SafeLdapContext");
return user;
}
@Override
public long getLastImportTime() throws Exception
{
_log.info("Getting last import time.");
long lastImportTime =
_defaultLDAPUserImporter.getLastImportTime();
_log.debug("Last import time: " + lastImportTime);
return lastImportTime;
}
@Override
public User importUser(long ldapServerId, long
companyId, String emailAddress, String screenName) throws Exception
{
_log.info("Entering importUser with email and
screenName");
_log.debug("Email Address: "
+ emailAddress + ", Screen Name: " + screenName);
User user = getDefaultLDAPUserImporter().importUser(ldapServerId,
companyId, emailAddress, screenName);
if (user != null)
{
_log.info("User imported successfully: " +
user.getFullName());
} else {
_log.warn("User import returned null.");
}
_log.info("Exiting importUser with email and
screenName");
return user;
}
@Override
public User importUser(long companyId, String
emailAddress, String screenName) throws Exception {
_log.info("Entering importUser without LDAP server");
_log.debug("Company ID: " + companyId + ", Email
Address: " + emailAddress + ", Screen Name: " + screenName);
User user = getDefaultLDAPUserImporter().importUser(companyId, emailAddress, screenName);
if (user != null) {
_log.info("User
imported successfully: " + user.getFullName());
}
else {
_log.warn("User import returned
null.");
}
_log.info("Exiting importUser without LDAP
server");
return user;
}
@Override
public User importUserByScreenName(long
companyId, String screenName) throws Exception {
_log.info("Entering importUserByScreenName");
_log.debug("Company ID: " + companyId + ", Screen Name:
" + screenName);
User user =
getDefaultLDAPUserImporter().importUserByScreenName(companyId,
screenName);
if (user != null) {
_log.info("User imported successfully: " +
user.getFullName());
} else {
_log.warn("User import returned null.");
}
_log.info("Exiting importUserByScreenName");
return user;
}
@Override
public User importUserByUuid(long ldapServerId,
long companyId, String uuid) throws Exception {
_log.info("Entering importUserByUuid with LDAP server");
_log.debug("LDAP Server ID: " + ldapServerId +
", Company ID: " + companyId + ", UUID: " + uuid);
User user = getDefaultLDAPUserImporter().importUserByUuid(ldapServerId, companyId, uuid);
if (user != null) {
_log.info("User
imported successfully: " + user.getFullName());
}
else {
_log.warn("User import returned
null.");
}
_log.info("Exiting importUserByUuid with LDAP
server");
return user;
}
@Override
public User importUserByUuid(long companyId,
String uuid) throws Exception {
_log.info("Entering
importUserByUuid without LDAP server");
_log.debug("Company ID: " + companyId + ", UUID: "
+ uuid);
User user = getDefaultLDAPUserImporter().importUserByUuid(companyId, uuid);
if (user != null) {
_log.info("User
imported successfully: " + user.getFullName());
}
else {
_log.warn("User import returned
null.");
}
_log.info("Exiting importUserByUuid without LDAP
server");
return user;
}
@Override
public void importUsers() throws Exception
{
_log.info("Entering global importUsers");
getDefaultLDAPUserImporter().importUsers();
_log.info("Exiting global importUsers");
}
@Override
public void importUsers(long companyId) throws
Exception {
_log.info("Entering importUsers for a
specific company");
_log.debug("Company ID:
" + companyId);
// Fetch users from LDAP
List<User>
usersFromLDAP = getUsersFromLDAP(companyId);
// Only import existing users
for (User user :
usersFromLDAP) {
try {
// Skip new
users or deactivate users based on your custom logic
_log.info("Importing user: " + user.getFullName());
getDefaultLDAPUserImporter().importUser(companyId,
user.getEmailAddress(), user.getScreenName());
} catch
(Exception e) {
_log.error("Error importing
user: " + user.getScreenName(), e);
}
}
_log.info("Exiting importUsers for a specific
company");
}
@Override
public void importUsers(long ldapServerId, long
companyId) throws Exception {
_log.info("Entering
importUsers for LDAP server and company");
_log.debug("LDAP Server ID: " + ldapServerId + ",
Company ID: " + companyId);
getDefaultLDAPUserImporter().importUsers(ldapServerId, companyId);
_log.info("Exiting importUsers for LDAP server and
company");
}
public List<User> getUsersFromLDAP(long companyId) {
List<User> users = new ArrayList<>();
try {
Collection<LDAPServerConfiguration>
ldapServerConfigurations =
_ldapServerConfigurationProvider.getConfigurations(companyId);
if (ldapServerConfigurations.isEmpty()) {
_log.error("No LDAP server configurations found for companyId:
" + companyId);
return users; // Return empty
list if no configurations are available
}
for (LDAPServerConfiguration ldapServerConfiguration :
ldapServerConfigurations) {
long ldapServerId =
ldapServerConfiguration.ldapServerId();
SafeLdapContext safeLdapContext =
_safePortalLDAP.getSafeLdapContext(
ldapServerId, companyId);
if (safeLdapContext ==
null) {
_log.warn("Failed to get
SafeLdapContext for LDAP server ID: " + ldapServerId);
continue;
}
String searchBase = ldapServerConfiguration.baseDN();
String searchFilter = "(objectClass=person)"; // Adjust
as needed
SearchControls searchControls = new
SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new
String[]{"uid", "mail", "givenName",
"sn"});
NamingEnumeration<SearchResult> results =
safeLdapContext.search(
searchBase,
searchFilter, searchControls);
// Process each
LDAP entry
while (results.hasMore()) {
SearchResult result = results.next();
Attributes attributes = result.getAttributes();
String screenName = getAttribute(attributes,
"displayName");
String email =
getAttribute(attributes, "mail");
String firstName = getAttribute(attributes,
"givenName");
String lastName =
getAttribute(attributes, "sn");
if
(Validator.isNull(email)) {
_log.warn("Skipping LDAP entry due to missing email: " +
result);
continue;
}
User existingUser =
UserLocalServiceUtil.fetchUserByEmailAddress(companyId, email);
if (existingUser != null) {
users.add(existingUser);
} else {
_log.info("User not found in Liferay: "
+ email);
}
}
safeLdapContext.close(); // Always close the context to
release resources
}
} catch (Exception e) {
_log.error("Error fetching users from LDAP", e);
}
return users;
}
private String
getAttribute(Attributes attributes, String attributeName) {
try {
if (attributes.get(attributeName) != null)
{
return (String)
attributes.get(attributeName).get();
}
}
catch (Exception e) {
_log.warn("Error retrieving
attribute: " + attributeName, e);
}
return null;
}
}
Thank You,
Vishal S Karjinni
Hi Vishal,
The image that would show the error I guess is broken for me. Could you please check it? Can you please share the error in text format for example?
Thanks,
Zsigmond
Hi Zsigmond,
Please check for errors in the text format. I am grateful for your time with us.
Exception in thread "liferay/scheduled_user_ldap_import-2"
java.lang.StackOverflowError
at
java.text.DateFormatSymbols.getProviderInstance(DateFormatSymbols.java:362)
at
java.text.DateFormatSymbols.getInstance(DateFormatSymbols.java:340)
at java.util.Calendar.getDisplayName(Calendar.java:2110)
at
java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1125)
at
java.text.SimpleDateFormat.format(SimpleDateFormat.java:966)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:936)
at
org.apache.log4j.pattern.DatePatternConverter$DefaultZoneDateFormat.format(DatePatternConverter.java:96)
at java.text.DateFormat.format(DateFormat.java:345)
at
org.apache.log4j.pattern.CachedDateFormat.format(CachedDateFormat.java:283)
at
org.apache.log4j.pattern.DatePatternConverter.format(DatePatternConverter.java:180)
at
org.apache.log4j.pattern.BridgePatternConverter.format(BridgePatternConverter.java:119)
at
org.apache.log4j.EnhancedPatternLayout.format(EnhancedPatternLayout.java:546)
at
org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:310)
at
org.apache.log4j.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:396)
at
org.apache.log4j.WriterAppender.append(WriterAppender.java:162)
at
org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
at
org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
at
org.apache.log4j.Category.callAppenders(Category.java:206)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.log(Category.java:856)
at
com.liferay.portal.log.Log4jLogImpl.info(Log4jLogImpl.java:79)
at
com.liferay.portal.kernel.log.LogWrapper.info(LogWrapper.java:123)
at
com.liferay.portal.kernel.log.SanitizerLogWrapper.info(SanitizerLogWrapper.java:139)
at
com.youngsoft.utils.ldapsync.service.CustomLDAPUserImporterImpl.getLastImportTime(CustomLDAPUserImporterImpl.java:82)
at
com.youngsoft.utils.ldapsync.service.CustomLDAPUserImporterImpl.getLastImportTime(CustomLDAPUserImporterImpl.java:83)
at
com.youngsoft.utils.ldapsync.service.CustomLDAPUserImporterImpl.getLastImportTime(CustomLDAPUserImporterImpl.java:83)
Thank you,
Vishal S Karjinni
Hi Vishal,
Well, in the source you shared the line 83 contains a } only, however, I think, the problem is at the
long lastImportTime = _defaultLDAPUserImporter.getLastImportTime();
call in the CustomLDAPUserImporterImpl.getLastImportTime() method. It seems to me from the code that the value of the _defaultLDAPUserImporter is an instance of the CustomLDAPUserImporterImpl so the call above always calls the same method which results a StackOverflowError. It should be debugged to make it sure, though.
Regards,
Zsigmond