Closed elettrico closed 6 years ago
Hi, can you give a bit more information about the error you are getting (stacktrace, where it crash, etc)?
This library is running in my example for 6 bots at the same time in same instances and I don't get any error.
Hi rubenlagus, it is not an error: in a java SE environment your example works perfectly, but it is forbidden in a java EE environment to use threads: creation, destruction and dafety of threads are managed by the container (glassfish, in this case) using beans. UpdatesThread run two threads for every bot, synchronizing them using a list, in java EE it's not necessary and "illegal", so I'm trying to modify the library source to adapt it to a java EE environment: using a Singleton bean and a timer for scheduling the update every 5 seconds seems to work. My changes to the code are far from being optimized, and I've to cut out some libraries for avoiding conflict (jersey is included in glassfish, for example), so I'be broken the webhook method, but if you want to see what I'm talking about I can mail you my experiment.
Sure, drop me a line at @ruben
Done. I'll wait your reply.
Hi elettrico I have a big issue with the integration of this library in my Spring MVC project...did you modify the library to work properly in Java EE? I explained my problem in this issue: https://github.com/rubenlagus/TelegramBots/issues/32
Il 15/04/2016 13:30, montalbano ha scritto:
Hi elettrico I have a big issue with the integration of this library in my Spring MVC project...did you modify the library to work properly in Java EE?
actually it's working. I don't know much about spring, but the big problem with java ee was the thread creation, I've changed the thread creation using beans that are managed by the container. maybe it's something similar in spring?
yes, but my problem is in the HOT REDEPLOY of glassfish:
Warning: Error invoking requestInitialized method on ServletRequestListener org.jboss.weld.servlet.WeldListener org.jboss.weld.exceptions.IllegalStateException: WELD-000227: Bean identifier index inconsistency detected - the distributed container probably does not work with identical applications Expected hash: 422265265 Current index: BeanIdentifierIndex [hash=-141639221, indexed=20]:
Bean identifier index inconsistency..and this block the whole application..I don't know why
There is another error in my stacktrace:
Grave: Exception in thread "Thread-41" Grave: java.lang.IllegalStateException: This web container has not yet been started at org.glassfish.web.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:2827) at org.glassfish.web.loader.WebappClassLoader.findResource(WebappClassLoader.java:1320) at org.glassfish.web.loader.WebappClassLoader.getResourceAsStream(WebappClassLoader.java:1528) at org.apache.http.util.VersionInfo.loadVersionInfo(VersionInfo.java:233) at org.apache.http.util.VersionInfo.getUserAgent(VersionInfo.java:319) at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:1046) at org.telegram.telegrambots.updatesreceivers.UpdatesThread$ReaderThread.run(UpdatesThread.java:62)
I googled for hours and found the solution: I set a new system property in glassfish
org.jboss.weld.serialization.beanIdentifierIndexOptimization = false
to avoid the appearing inconsistencies as explained in the WELD reference here: link
@elettrico May this solve also your issues with it?
Hi ruben, I didn't have this kind of issue because I've changed the thread model for a bean model: in a EE environment it's a bad practice to use threads: threads have to be managed by the container because it's the container that knows when a thread is needed and when to end it. So I prefer to use beans and let the container (glassfish, in my case) to manage the life of the processes as java EE specificacion suggest. In case of hot redeploy (or not) there are no thread that start before the complete initialization of his container: the org.telegram.telegrambots.updatesreceivers.UpdatesThread$ReaderThread use threads, instead I have a singleton started by glassfish when it's ready and killed during the undeploy. This stackoverflow thread about threads and java EE is interesting http://stackoverflow.com/questions/3212255/java-ee-specification-and-multi-threading Thank you
Hi @elettrico @rubenlagus ! Well, did you find a solution for the correct integration TelegramBots with Java EE environment?
@montalbano could u provide an example how did you fixed the issue?
@elettrico could you show me what did you changed
basically I've created and interface and an abstract class for using with bean, the are copies of the ITelegramLongPollingBot and TelegramLongPollingBot. then I've created an UpdatesBean as a @Singleton and instead of using threads I've used @Schedule annotation for the update method. of course I've added a registerBot(TelegramBeanPollingBot bot) method in TelegramBotsApi class. after that I've created another singleton, TelegramSession, in which I inject UpdatesBean and my bot handler, a bean extending TelegramBeanPollingBot. the last thing I've done is a @Singleton @Startup that use TelegramSession singleton to start the session in @PostConstruct and stop it in @PreDestroy. in this way all the threads are managed as beans by the container.
I simply set a system property in Glassfish Admin Panel to avoid the bean Identifier Index Optimization.
1) Right Click on the server and choose: "View Domain Admin Console"
2) Configurations -> Server-config -> System properties
3) Click Add Property and add this:
org.jboss.weld.serialization.beanIdentifierIndexOptimization = false
Detected one more threads issue.
When using spring boot with spring-boot-devtools
Automatic restart feature new ReaderThread
and HandlerThread
are starting on spring boot "hot restart".
Only "cold" restart (i mean killing jvm :) ) allows original ReaderThread
and HandlerThread
to stop. Here is an debugger picture after "hot restarting" 3 times:
OK, i sloved that "problem" like this:
@Component
public class Worker implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(Worker.class);
@Autowired
private MyTelegramBot bot;
@Autowired
private TelegramBotsApi telegramBotsApi;
private BotSession botSession;
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
try {
botSession = telegramBotsApi.registerBot(bot);
} catch (TelegramApiException e) {
log.error(e.getApiResponse(), e);
}
}
@PreDestroy
public void tearDown() {
botSession.close();
}
}
So on every hot restart request tearDown()
is fired and threads ReaderThread
and HandlerThread
are closed via BotSession.close()
I'm getting this error No implementation for org.telegram.telegrambots.generics.BotSession was bound using spring boot
@SpringBootApplication
public class AutoDownloaderApplication implements CommandLineRunner {
@Autowired
private MovieGrabber movieGrabber;
@Autowired
private TelegramBotsApi telegramBotsApi;
private BotSession botSession;
@Override
public void run(String... args) throws Exception {
botSession = telegramBotsApi.registerBot(movieGrabber);
}
@Bean
public TelegramBotsApi getTelegramBotsApi() {
return new TelegramBotsApi();
}
@PreDestroy
public void tearDown() {
botSession.close();
}
public static void main(String[] args) throws Exception {
SpringApplication.run(AutoDownloaderApplication.class, args);
}
}
Hello, I am trying to use telegram api inside JSF CDI container. Your example bots are working well but I got this error repeatedly 409 [Error]: Conflict: terminated by other long poll or webhook. I try to initialize TelegramBotApi inside ServletContextListener and close botSection when context is destroyed. Here is code. @WebListener public class WebContextListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(WebContextListener.class);
private BotSession botSession;
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
LOGGER.debug("Web context initialisation has been started");
try {
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
// Register long polling bots. They work regardless type of TelegramBotsApi we are creating
botSession=telegramBotsApi.registerBot(new CommandsHandler());
} catch (TelegramApiException e) {
BotLogger.error("Initialize", e);
}
} catch (Exception e) {
BotLogger.error("Initialize", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
LOGGER.info("contextDestroyed start");
botSession.close();
LOGGER.info("Bot stop");
}
}
I fixed this problem and faced with another one but everything is working well, when I stop each time WildFly JBoss server it is showing this exception BOTSESSION: java.net.SocketException: Socket closed. maybe I am doing something wrong. How to implement your library for CDI JAVA EE application? Please give me any idea. Thank you
@Boburmirzo I think your second problem is related to #168
Regarding first one, just make sure that you are not registering the same bot twice. Remember that you can only run one concurrent getUpdates request.
@elettrico Hi, i'm facing the same issue, the problem occurs when i register the Bots inside a session bean. Could you or any one else who has managed to overcome the problem give a more detailed answer or when possible the modified version of this api? Thank you in advance!
Hello @elettrico, Which container are you using? In our case, we used JSF CDI container, I register bots when servlet context is initialized and stop when context is destroyed. For example, we are using Shiro web environment by customizing EnvironmentLoaderListener class like this:
public class CustomEnvironmentLoaderListener extends EnvironmentLoaderListener {
@Inject
private OrdersBotLongPolling ordersBotLongPolling;
// make sure that BotPolling class should be annotated
// @named and @Dependent if you are using JSF CDI beans
...................................................
private DefaultBotSession ordersBotSession;
private DefaultBotSession productsBotSession;
.....................
@Override
protected WebEnvironment createEnvironment(ServletContext pServletContext) {
............................
registerBots();
}
private void registerBots() { LOGGER.debug("Telegram bots initialisations has been started"); ApiContextInitializer.init(); registerOrdersBot(); }
private void registerOrdersBot() { LOGGER.debug("Initializing Likada Orders Bot"); try { ordersBotLongPolling.clearWebhook(); ordersBotLongPolling.register(firstcommand); ordersBotLongPolling.register(secondcommand); ordersBotSession = ApiContext.getInstance(DefaultBotSession.class); ordersBotSession.setToken(ordersBotLongPolling.getBotToken()); ordersBotSession.setOptions(ordersBotLongPolling.getOptions()); ordersBotSession.setCallback(ordersBotLongPolling); ordersBotSession.start(); } catch (TelegramApiException e) { BotLogger.error("Initialize", e); } } @Override public void destroyEnvironment(ServletContext servletContext) { super.destroyEnvironment(servletContext); productsBotSession.stop(); ordersBotSession.stop(); LOGGER.info("Bots are stopped"); } }
if you would like to inject all you beans inside bot controller, put annotation like following:
@Named @ApplicationScoped public class OrdersBotController { @Inject private TelegramUserService telegramUserService; } We also tried to put Bot inside a session bean, but It does not work. Then, we put inside Application scope
I hope it will help you to solve your problem. Thanks
I use EJB session beans. As in the image, i intend to initialize my Bots in a singelton sessino bean, like a Main thread in a standard java application. Do you think it's a good approach? shoud i continue this way in order to deploy my bot on a remote server(i'm using openshift as webserver)? Any ideas or suggestions would be appreciated!
Hi elettrico
you posted a solution on commented on Apr 20, 2016. However this is very unclear. Can you please upload the sample to your GitHub repository?
Is it now possible to use this library in a J2EE container like Jboss, WildFly or Tomcat ? I'm asking because I see this issue as closed
Thank you
Hi, I'm trying to use telegram api inside an entreprise application. It is working but there are a lot of problem due to thread generations UpdatesThread.java, because threads conflict with the container. Is there a way to use your library in java EE or do you know any working implementation? Thank you