180 const std::string & base_package,
const std::string & base_class,
const std::set<std::string> & exclude_packages,
181 const std::map<std::string, std::string> & reserved_names)
183 std::map<std::string, std::vector<std::string>> packages_for_class_name;
185 for (
const auto & package : packages) {
186 auto single_package_loader =
187 pluginlib::ClassLoader<BaseT>(base_package, base_class,
"", {
getPluginXMLPath(package)});
188 for (
const auto & class_name : single_package_loader.getDeclaredClasses()) {
189 packages_for_class_name[class_name].push_back(package);
194 for (
const auto & [class_name, package] : reserved_names) {
195 packages_for_class_name[class_name].push_back(package);
199 std::vector<std::string> error_details;
200 for (
const auto & [class_name, packages] : packages_for_class_name) {
201 if (packages.size() > 1) {
202 error_details.push_back(
203 "- Class '" + class_name +
"' found in packages ['" + auto_apms_util::join(packages,
"', '") +
"'].");
206 if (!error_details.empty()) {
207 throw exceptions::ResourceError(
208 "Ambiguous class names found! PluginClassLoader (Base: " + base_class +
209 ") created with makeUnambiguousPluginClassLoader() won't register resources from packages "
210 "that use already existing lookup names. Found the following duplicates:\n" +
211 auto_apms_util::join(error_details,
"\n"));
213 return {base_package, base_class, exclude_packages};