Всем привет!
Приложение Spring Boot 2.1.5 на Tomcat 8.5. Приложение использует jar-библиотеку, через которую выбирает нужную реализацию.
Есть одна встроенная реализация сохранения в файл: класс "com.company.scjms.ListenerToFile", который находится в jar-нике.
Через "registrateMessageAsyncConsumerFactory()" можно добавлять новые реализации:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
package com.company.scjms;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class ListenerFactory {
private static final String exceptionConsumerInstance
= "Failed get message async consumer instance";
private static Map<String, String> listenerMap = new HashMap<>();
static {
listenerMap.put(
"defaultListener",
"com.company.scjms.ListenerToFile");
}
public static AsyncConsumer getInstance(
String messageAsyncConsumerShortName)
throws MessageServiceException {
try {
Class clazz = Class.forName(
listenerMap.get(messageAsyncConsumerShortName));
return (AsyncConsumer) clazz.getConstructor().newInstance();
} catch (ClassNotFoundException
| NoSuchMethodException
| SecurityException
| InstantiationException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException ex) {
throw new MessageServiceException(exceptionConsumerInstance, ex);
}
}
public static void registrateMessageAsyncConsumerFactory(
String shortName,
String className) {
listenerMap.put(shortName, className);
}
}
Возникает необходимость в самом Spring Boot приложении добавить новую реализацию, например, запись в БД:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
package com.company.scjmslistener;
@Component
public class Consumer {
private MessageService messageService;
private final String shortName = "MariaDB";
private final String className
= "com.company.scjmslistener.ListenerToDB";
@PostConstruct
public void init() {
ListenerFactory.registrateMessageAsyncConsumerFactory(
shortName,
className);
...
}
}
При попытке вернуть экземпляр класса "ListenerToDB" через "public static AsyncConsumer getInstance()" возникает ошибка:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consumer': Invocation of init method failed; nested exception is java.lang.RuntimeException: com.company.scjms.MessageServiceException: Failed get message async consumer instance
Caused by: com.company.scjms.MessageServiceException: Failed get message async consumer instance
at com.company.scjms.ListenerFactory.getInstance(ListenerFactory.java:34) ~[scjms-1.07.jar:na]
at com.company.scjms.ActiveMQMessageService.connect(ActiveMQMessageService.java:142) ~[scjms-1.07.jar:na]
at com.company.scjmslistener.Consumer.init(Consumer.java:50) ~[classes/:na]
... 60 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.company.scjmslistener.ListenerToDB.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_212]
at java.lang.Class.getConstructor(Class.java:1825) ~[na:1.8.0_212]
at com.company.scjms.ListenerFactory.getInstance(ListenerFactory.java:26) ~[scjms-1.07.jar:na]
... 62 common frames omitted
Как я понимаю jar-ник не может найти класс "com.company.scjmslistener.ListenerToDB", как минимум потому что новый класс находится в другом пакете.
Куда и в каком виде нужно положить мою новую реализацию класс "com.company.scjmslistener.ListenerToDB", чтобы jar-ник видел его и возвращал его экземпляр?