Ваша проблема в том, что вы неправильно поняли цель сервлета . Он намерен действовать по HTTP-запросам, не более того. Вам нужна только фоновая задача, которая выполняется один раз на ежедневной основе.
@Schedule
Если ваша среда поддерживает EJB (например, WildFly, JBoss AS / EAP, TomEE, GlassFish и т. Д.), Тогда используйте @Schedule
.
@Singleton
public class BackgroundJobManager {
@Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
@Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
@Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
}
Да, это действительно все. Контейнер автоматически подберет и управляет им.
ScheduledExecutorService
Если ваша среда не поддерживает EJB (то есть не настоящий Java EE-сервер, например Tomcat, Jetty и т. Д.), Используйте ScheduledExecutorService
. Это может быть инициировано ServletContextListener
. Вот пример kickoff:
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Если классы заданий выглядят следующим образом:
public class SomeDailyJob implements Runnable {
@Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
@Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
@Override
public void run() {
// Do your quarterly job here.
}
}
java.util.Timer
/ java.lang.Thread
в Java EE Никогда не используйте java.util.Timer
и / или java.lang.Thread
в Java EE. Это рецепт неприятностей. Подробное объяснение можно найти в этом ответе JSF по одному и тому же вопросу: Истеризация потоков в управляемом компоненте JSF для запланированных задач с использованием таймера .
См. http://www.rubygems.org/read/chapter/11 и укажите ~/.gemrc
, который определяет gemhome переменную.
, Например:
gemhome: /usr/local/rubygems
можно также поместить этот файл в /etc/gemrc
, Кроме того, можно установить GEM_HOME
огибающая переменная :
$ export GEM_HOME=/tmp/gemtest
$ gem install bundler
$ ls /tmp/gemtest/bin/
bundle
Обновление (10 лет спустя):
Andrey Rodionov ниже предлагают использовать
gem: --bindir /usr/bin
На OS X исполняемый каталог переопределяется к /usr/bin
в файле /Library/Ruby/Site/1.8/rubygems/defaults.rb
# The default directory for binaries
def self.default_bindir
if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
'/usr/bin'
else # generic install
ConfigMap[:bindir]
end
end
Как работа hackish вокруг, я изменился /usr/bin
на свое желаемое местоположение мусорного ведра, которое работает правильно. Кажется, нет никакого способа переопределить bindir от эти ~/.gemrc
конфигурация?
Я добавляю это как ответ чтобы это было очевидно, когда я снова столкнусь с этой проблемой :)
Сначала переместите все бункеры из /var/lib/gems/1.8/bin/
в / usr / bin /
. Если вы этого не сделаете, то удаление или обновление гема не приведет к удалению двоичного файла из исходного каталога bin.
Вы также можете удалить старый путь из $ PATH
Затем отредактируйте ~ / .gemrc
и добавьте (или обновите) следующую строку:
gem: --bindir /usr/bin
Это отменяет gem так что он всегда использует / usr / bin / в качестве каталога bin.
Нет необходимости обновлять путь (особенно беспорядок для многопользовательских машин).