You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2012/03/28 14:48:41 UTC
svn commit: r1306294 - in
/incubator/syncope/trunk/core/src/main/java/org/syncope/core: init/
rest/controller/ rest/data/
Author: ilgrosso
Date: Wed Mar 28 12:48:40 2012
New Revision: 1306294
URL: http://svn.apache.org/viewvc?rev=1306294&view=rev
Log:
[SYNCOPE-50] A separated ImplementationClassNamesLoader class, invoked on webapp init, has been provided: this will make things easier in WAR overlays
Added:
incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java (with props)
Modified:
incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/SpringContextInitializer.java
incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java
incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java
incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java
incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ReportDataBinder.java
Added: incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java?rev=1306294&view=auto
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java (added)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java Wed Mar 28 12:48:40 2012
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.syncope.core.init;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.quartz.Job;
+import org.quartz.StatefulJob;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.ClassMetadata;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+import org.syncope.core.persistence.validation.attrvalue.Validator;
+import org.syncope.core.report.Reportlet;
+import org.syncope.core.scheduling.NotificationJob;
+import org.syncope.core.scheduling.ReportJob;
+import org.syncope.core.scheduling.SyncJob;
+import org.syncope.core.scheduling.SyncJobActions;
+
+/**
+ * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
+ */
+@Component
+public class ImplementationClassNamesLoader {
+
+ public enum Type {
+
+ REPORTLET,
+ JOB,
+ JOB_ACTIONS,
+ VALIDATOR
+
+ }
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ImplementationClassNamesLoader.class);
+
+ @Autowired
+ private ResourcePatternResolver resResolver;
+
+ private Map<Type, Set<String>> classNames;
+
+ public void load() {
+ CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
+
+ classNames = new EnumMap<Type, Set<String>>(Type.class);
+ for (Type type : Type.values()) {
+ classNames.put(type, new HashSet<String>());
+ }
+
+ try {
+ for (Resource resource : resResolver.getResources("classpath*:**/*.class")) {
+ ClassMetadata metadata = factory.getMetadataReader(resource).getClassMetadata();
+
+ try {
+ Class clazz = ClassUtils.forName(metadata.getClassName(), ClassUtils.getDefaultClassLoader());
+ Set<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(clazz);
+
+ if (interfaces.contains(Reportlet.class) && !metadata.isAbstract()) {
+ classNames.get(Type.REPORTLET).add(clazz.getName());
+ }
+
+ if ((interfaces.contains(Job.class) || interfaces.contains(StatefulJob.class))
+ && !metadata.isAbstract() && !SyncJob.class.getName().equals(metadata.getClassName())
+ && !ReportJob.class.getName().equals(metadata.getClassName())
+ && !NotificationJob.class.getName().equals(metadata.getClassName())) {
+
+ classNames.get(Type.JOB).add(metadata.getClassName());
+ }
+
+ if (interfaces.contains(SyncJobActions.class) && !metadata.isAbstract()) {
+ classNames.get(Type.JOB_ACTIONS).add(metadata.getClassName());
+ }
+
+ if (interfaces.contains(Validator.class) && !metadata.isAbstract()) {
+ classNames.get(Type.VALIDATOR).add(metadata.getClassName());
+ }
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not load class {}", metadata.getClassName());
+ } catch (LinkageError e) {
+ LOG.warn("Could not link class {}", metadata.getClassName());
+ }
+ }
+ } catch (IOException e) {
+ LOG.error("While searching for class implementing {}", Reportlet.class.getName(), e);
+ }
+
+ classNames = Collections.unmodifiableMap(classNames);
+
+ LOG.debug("Implementation classes found: {}", classNames);
+ }
+
+ public Set<String> getClassNames(final Type type) {
+ return classNames.get(type);
+ }
+}
Propchange: incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/ImplementationClassNamesLoader.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/SpringContextInitializer.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/SpringContextInitializer.java?rev=1306294&r1=1306293&r2=1306294&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/SpringContextInitializer.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/init/SpringContextInitializer.java Wed Mar 28 12:48:40 2012
@@ -48,6 +48,9 @@ public class SpringContextInitializer im
@Autowired
private LoggerLoader loggerLoader;
+ @Autowired
+ private ImplementationClassNamesLoader classNamesLoader;
+
@Override
public void setServletContext(final ServletContext servletContext) {
}
@@ -64,5 +67,6 @@ public class SpringContextInitializer im
jobInstanceLoader.load();
activitiWorkflowLoader.load();
loggerLoader.load();
+ classNamesLoader.load();
}
}
Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java?rev=1306294&r1=1306293&r2=1306294&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java Wed Mar 28 12:48:40 2012
@@ -28,13 +28,10 @@ import javax.servlet.http.HttpServletRes
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.ClassMetadata;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -42,6 +39,7 @@ import org.springframework.web.bind.anno
import org.springframework.web.servlet.ModelAndView;
import org.syncope.client.to.ConfigurationTO;
import org.syncope.core.audit.AuditManager;
+import org.syncope.core.init.ImplementationClassNamesLoader;
import org.syncope.core.persistence.beans.SyncopeConf;
import org.syncope.core.persistence.dao.ConfDAO;
import org.syncope.core.persistence.dao.MissingConfKeyException;
@@ -69,12 +67,15 @@ public class ConfigurationController ext
private ImportExport importExport;
@Autowired
+ private ImplementationClassNamesLoader classNamesLoader;
+
+ @Autowired
private ResourcePatternResolver resResolver;
@PreAuthorize("hasRole('CONFIGURATION_CREATE')")
@RequestMapping(method = RequestMethod.POST, value = "/create")
- public ConfigurationTO create(final HttpServletResponse response, @RequestBody final ConfigurationTO configurationTO) {
-
+ public ConfigurationTO create(final HttpServletResponse response,
+ @RequestBody final ConfigurationTO configurationTO) {
LOG.debug("Configuration create called with parameters {}", configurationTO);
SyncopeConf conf = configurationDataBinder.createSyncopeConfiguration(configurationTO);
@@ -157,29 +158,7 @@ public class ConfigurationController ext
@PreAuthorize("hasRole('CONFIGURATION_LIST')")
@RequestMapping(method = RequestMethod.GET, value = "/validators")
public ModelAndView getValidators() {
- CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
-
- Set<String> validators = new HashSet<String>();
- try {
- for (Resource resource : resResolver
- .getResources("classpath:org/syncope/core/persistence/validation/attrvalue/*.class")) {
-
- ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata();
-
- try {
- Set<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata
- .getClassName(), ClassUtils.getDefaultClassLoader()));
-
- if (interfaces.contains(Validator.class) && !metadata.isAbstract()) {
- validators.add(metadata.getClassName());
- }
- } catch (ClassNotFoundException e) {
- LOG.error("Could not load class {}", metadata.getClassName(), e);
- }
- }
- } catch (IOException e) {
- LOG.error("While searching for class implementing {}", Validator.class.getName(), e);
- }
+ Set<String> validators = classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.VALIDATOR);
auditManager.audit(Category.configuration, ConfigurationSubCategory.getValidators, Result.success,
"Successfully listed all validators: " + validators.size());
@@ -198,11 +177,11 @@ public class ConfigurationController ext
String template = resource.getURL().toExternalForm();
if (template.endsWith(".html.vm")) {
- htmlTemplates.add(template.substring(template.indexOf("mailTemplates/") + 14, template
- .indexOf(".html.vm")));
+ htmlTemplates.add(
+ template.substring(template.indexOf("mailTemplates/") + 14, template.indexOf(".html.vm")));
} else if (template.endsWith(".txt.vm")) {
- textTemplates.add(template.substring(template.indexOf("mailTemplates/") + 14, template
- .indexOf(".txt.vm")));
+ textTemplates.add(
+ template.substring(template.indexOf("mailTemplates/") + 14, template.indexOf(".txt.vm")));
} else {
LOG.warn("Unexpected template found: {}, ignoring...", template);
}
Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java?rev=1306294&r1=1306293&r2=1306294&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java Wed Mar 28 12:48:40 2012
@@ -41,7 +41,6 @@ import org.apache.xmlgraphics.util.MimeC
import org.quartz.JobDataMap;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@@ -96,9 +95,6 @@ public class ReportController extends Ab
@Autowired
private ReportDataBinder binder;
- @Autowired
- private ResourcePatternResolver resResolver;
-
@PreAuthorize("hasRole('REPORT_CREATE')")
@RequestMapping(method = RequestMethod.POST, value = "/create")
public ReportTO create(final HttpServletResponse response, @RequestBody final ReportTO reportTO) {
Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java?rev=1306294&r1=1306293&r2=1306294&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java Wed Mar 28 12:48:40 2012
@@ -18,28 +18,19 @@
*/
package org.syncope.core.rest.controller;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javassist.NotFoundException;
import javax.servlet.http.HttpServletResponse;
-import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.Scheduler;
-import org.quartz.StatefulJob;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.ClassMetadata;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
-import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -53,6 +44,7 @@ import org.syncope.client.to.TaskTO;
import org.syncope.client.validation.SyncopeClientCompositeErrorException;
import org.syncope.client.validation.SyncopeClientException;
import org.syncope.core.audit.AuditManager;
+import org.syncope.core.init.ImplementationClassNamesLoader;
import org.syncope.core.init.JobInstanceLoader;
import org.syncope.core.notification.NotificationManager;
import org.syncope.core.persistence.beans.NotificationTask;
@@ -65,10 +57,6 @@ import org.syncope.core.persistence.dao.
import org.syncope.core.propagation.PropagationManager;
import org.syncope.core.rest.data.TaskDataBinder;
import org.syncope.core.scheduling.AbstractTaskJob;
-import org.syncope.core.scheduling.NotificationJob;
-import org.syncope.core.scheduling.ReportJob;
-import org.syncope.core.scheduling.SyncJob;
-import org.syncope.core.scheduling.SyncJobActions;
import org.syncope.core.util.TaskUtil;
import org.syncope.types.AuditElements.Category;
import org.syncope.types.AuditElements.Result;
@@ -106,7 +94,7 @@ public class TaskController extends Abst
private SchedulerFactoryBean scheduler;
@Autowired
- private ResourcePatternResolver resResolver;
+ private ImplementationClassNamesLoader classNamesLoader;
@PreAuthorize("hasRole('TASK_CREATE')")
@RequestMapping(method = RequestMethod.POST, value = "/create/sync")
@@ -252,32 +240,7 @@ public class TaskController extends Abst
@PreAuthorize("hasRole('TASK_LIST')")
@RequestMapping(method = RequestMethod.GET, value = "/jobClasses")
public ModelAndView getJobClasses() {
- CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
-
- Set<String> jobClasses = new HashSet<String>();
- try {
- for (Resource resource : resResolver.getResources("classpath*:**/*.class")) {
-
- ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata();
-
- try {
- Set<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata.
- getClassName(), ClassUtils.getDefaultClassLoader()));
-
- if ((interfaces.contains(Job.class) || interfaces.contains(StatefulJob.class))
- && !metadata.isAbstract() && !SyncJob.class.getName().equals(metadata.getClassName())
- && !ReportJob.class.getName().equals(metadata.getClassName())
- && !NotificationJob.class.getName().equals(metadata.getClassName())) {
-
- jobClasses.add(metadata.getClassName());
- }
- } catch (ClassNotFoundException e) {
- LOG.error("Could not load class {}", metadata.getClassName(), e);
- }
- }
- } catch (IOException e) {
- LOG.error("While searching for class implementing {}", Job.class.getName(), e);
- }
+ Set<String> jobClasses = classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.JOB);
auditManager.audit(Category.task, TaskSubCategory.getJobClasses, Result.success,
"Successfully listed all Job classes: " + jobClasses.size());
@@ -288,27 +251,7 @@ public class TaskController extends Abst
@PreAuthorize("hasRole('TASK_LIST')")
@RequestMapping(method = RequestMethod.GET, value = "/jobActionsClasses")
public ModelAndView getJobActionClasses() {
- CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
-
- Set<String> jobActionsClasses = new HashSet<String>();
- try {
- for (Resource resource : resResolver.getResources("classpath*:**/*.class")) {
- ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata();
-
- try {
- Set<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata.
- getClassName(), ClassUtils.getDefaultClassLoader()));
-
- if (interfaces.contains(SyncJobActions.class) && !metadata.isAbstract()) {
- jobActionsClasses.add(metadata.getClassName());
- }
- } catch (ClassNotFoundException e) {
- LOG.error("Could not load class {}", metadata.getClassName(), e);
- }
- }
- } catch (IOException e) {
- LOG.error("While searching for class implementing {}", SyncJobActions.class.getName(), e);
- }
+ Set<String> jobActionsClasses = classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.JOB_ACTIONS);
auditManager.audit(Category.task, TaskSubCategory.getJobActionClasses, Result.success,
"Successfully listed all SyncJobActions classes: " + jobActionsClasses.size());
Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ReportDataBinder.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ReportDataBinder.java?rev=1306294&r1=1306293&r2=1306294&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ReportDataBinder.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ReportDataBinder.java Wed Mar 28 12:48:40 2012
@@ -18,7 +18,6 @@
*/
package org.syncope.core.rest.data;
-import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.quartz.Scheduler;
@@ -28,16 +27,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.ClassMetadata;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.syncope.client.report.ReportletConf;
import org.syncope.client.to.ReportExecTO;
import org.syncope.client.to.ReportTO;
+import org.syncope.core.init.ImplementationClassNamesLoader;
import org.syncope.core.init.JobInstanceLoader;
import org.syncope.core.persistence.beans.Report;
import org.syncope.core.persistence.beans.ReportExec;
@@ -53,9 +49,9 @@ public class ReportDataBinder {
*/
private static final Logger LOG = LoggerFactory.getLogger(ReportDataBinder.class);
- private static final String[] IGNORE_REPORT_PROPERTIES = { "id", "reportlets", "executions", "latestExecStatus" };
+ private static final String[] IGNORE_REPORT_PROPERTIES = {"id", "reportlets", "executions", "latestExecStatus"};
- private static final String[] IGNORE_REPORT_EXECUTION_PROPERTIES = { "id", "report", "execResult" };
+ private static final String[] IGNORE_REPORT_EXECUTION_PROPERTIES = {"id", "report", "execResult"};
@Autowired
private ReportExecDAO reportExecDAO;
@@ -64,31 +60,21 @@ public class ReportDataBinder {
private SchedulerFactoryBean scheduler;
@Autowired
- private ResourcePatternResolver resResolver;
+ private ImplementationClassNamesLoader classNamesLoader;
public Set<Class<Reportlet>> getAllReportletClasses() {
- CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
-
Set<Class<Reportlet>> reportletClasses = new HashSet<Class<Reportlet>>();
- try {
- for (Resource resource : resResolver.getResources("classpath*:**/*.class")) {
- ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata();
- try {
- Class reportletClass = ClassUtils.forName(metadata.getClassName(), ClassUtils
- .getDefaultClassLoader());
- Set<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(reportletClass);
- if (interfaces.contains(Reportlet.class) && !metadata.isAbstract()) {
- reportletClasses.add(reportletClass);
- }
- } catch (ClassNotFoundException e) {
- LOG.error("Could not load class {}", metadata.getClassName(), e);
- }
+ for (String className : classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET)) {
+ try {
+ Class reportletClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
+ reportletClasses.add(reportletClass);
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not load class {}", className);
+ } catch (LinkageError e) {
+ LOG.warn("Could not link class {}", className);
}
- } catch (IOException e) {
- LOG.error("While searching for class implementing {}", Reportlet.class.getName(), e);
}
-
return reportletClasses;
}