Страницы

Поиск по вопросам

среда, 13 марта 2019 г.

javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread

GenericDao.java:
@Repository public abstract class GenericDao implements GeneralDao {
private Class className;
public GenericDao(Class className) { this.className = className; }
@PersistenceContext private EntityManager entityManager;
public EntityManager getEntityManager() { return entityManager; }
@Override public void add(T object) { try { getEntityManager().persist(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.ADD_ENTITY_FAIL, e); } }
@Override public void update(T object) { try { getEntityManager().merge(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.UPDATE_ENTITY_FAIL, e); } }
@Override public void remove(T object) { try { getEntityManager().remove(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.REMOVE_ENTITY_FAIL, e); } }
@Override public T getById(int id) { try { return getEntityManager().find(this.className, id); } catch (HibernateException e) { throw new DaoException(ErrorMessage.GET_BY_ID_ENTITY_FAIL, e); } }
public abstract List getAll() throws DaoException;
}
GenericService.java
@Service public abstract class GenericService implements GeneralService { private static Logger logger = Logger.getLogger(GenericService.class);
@Autowired private GenericDao dao;
@Transactional @Override public void add(T object) throws ServiceException { try { dao.add(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional @Override public void update(T object) throws ServiceException { try { dao.update(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional @Override public void remove(T object) throws ServiceException { try { dao.remove(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional(readOnly = true) @Override public T getById(int id) throws ServiceException { try { return dao.getById(id); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional(readOnly = true) @Override public List getAll() throws ServiceException { try { return dao.getAll(); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
}
UserServiceImpl.java:
@Service public class UserServiceImpl extends GenericService implements UserService { private static Logger logger = Logger.getLogger(UserServiceImpl.class);
@Autowired private UserDao userDao;
@Transactional @Override public String checkUser(String userLogin, String userPassword) throws ServiceException { String namePage = "errorAuthorization"; List userList; try { userList = userDao.getByLoginAndPassword(userLogin, userPassword); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } if(userList.size() != 0) { return UserRoleChecker.defineUserPage(userList.get(0)); } return namePage; }
@Transactional @Override public void addUser(String userLogin, String userPassword, String userMail) throws ServiceException { Role role = new Role(0L, RoleType.USER); User user = new User(0L, userLogin, userPassword, userMail, role); add(user); }
}
UserController.java:
@Controller public class UserController { private static String className = UserController.class.getName(); private static Logger logger = Logger.getLogger(UserController.class.getName());
@Autowired private UserService userService;
@RequestMapping(value = "/check_user", method = RequestMethod.POST) public ModelAndView authorizationUser(HttpServletRequest request, HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); String returnPage; try { returnPage = userService.checkUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD)); } catch (ServiceException e) { logger.debug(e); returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); } modelAndView.setViewName(returnPage); return modelAndView; }
@RequestMapping(value = "/add_user", method = RequestMethod.POST) public ModelAndView registrationUser(HttpServletRequest request, HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); String returnPage = Page.SUCCESSFUL_REGISTRATION; try { userService.addUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD), request.getParameter(RequestParameter.USER_MAIL)); } catch (ServiceException e) { logger.debug(e); returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); } modelAndView.setViewName(returnPage); return modelAndView; }
}
root-context.xml:




org.hibernate.dialect.MySQLDialect true true 2 true update





logs:
org.springframework.web.servlet.FrameworkServlet 2017-05-10 22:23:59,107 DEBUG - Could not complete request javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:282) at com.sun.proxy.$Proxy27.persist(Unknown Source) at by.netcracker.artemyev.dao.GenericDao.add(GenericDao.java:35) at by.netcracker.artemyev.service.GenericService.add(GenericService.java:24) at by.netcracker.artemyev.service.impl.UserServiceImpl.addUser(UserServiceImpl.java:48) at by.netcracker.artemyev.web.UserController.registrationUser(UserController.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:495) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:767) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1354) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
Почему возникает эта ошибка и как её исправить?


Ответ

Проблема в том, что spring не строит прокси-объект поверх UserServiceImpl, а внедряет его напрямую в UserController, что видно из твоего исключения.
Причины, я полагаю, в том, что твой root-context.xml относится к контексту всего приложения, т.е. инициализируется через ContextLoaderListener. Внутри указанного контекста UserServiceImpl имеет транзакционность. Однако, у тебя также имеется некая конфигурация (тут лучше бы приложить web.xml) относящаяся к DispatcherServlet, в которой инициализируется UserController и как раз нет tx:annotation-driven. Соответственно в UserController попадет чистый бин, а не его прокси.
Быстро решить данную проблему можно убрав @Service с самого класса UserServiceImpl и определив его в root-context.xml

“Портативное” PHP или Python/Django web приложение

Существует ли возможность сделать PHP или Python/Django приложение переносным т.е. скопировать на флешку и запустить на другом компьютере? Все выглядеть должно примерно так:
Само приложение написано на PHP или Python/Django, база данных SQLite Интерпретатор и библиотеки НЕ устанавливается отдельно, а тянутся вместе с приложением в архиве При клике на ярлык запуска приложения, запускается встроенный в Python или PHP http сервер(есть в версиях >= 5.4) на свободном порту (например: 127.0.0.1:8080) После запуска сервера, запускается web браузер и открывает главную страницу приложения на адресе и порте которые использует web сервер (например: http://127.0.0.1:8080/)
Получится что-то вроде десктопного приложения, но только работать будет в браузере ) Я понимаю что это полное извращение, но есть обстоятельства которые не позволяют сделать по другому (разве что пилить полноценное десктопное приложение, на которое нет времени и бюджета)


Ответ

Python версия.
Два варианта, первый сделать самому, второе взять готовое но чуть более старое например, http://portablepython.com/.
Про первый вариант подробнее.
Python не тянет особых зависимостей, поэтому устанавливаем (берем со своего компьютера) python, полностью всю папку и закидываем на флешку.
Далее в эту же папку ставим все модули и зависимые пакеты, в том числе и наше приложение на django.
Пишем простой бат файл, который переходит в папку питона и запускает наш проект, примерно вот так
cd python27 cd myproject usr\bin\python27.exe manage.py runserver 0.0.0.0:8123
Проверка занятых портов и прочее ложиться на уровень запускающего файла.
PHP версия. Аналогично питону можно самому собрать нужное, можно взять готовый portable пакет, например http://www.usbwebserver.net/en/download.php Там все еще проще, в папку копируется сайт, сам сервер при необходимости запускается из папки. Значки запуска у большинства есть готовые.

Как использовать Twig

У меня небольшой проект (mvc,OOP). Покажите пожалуйста как правильно подключать Twig и как его использовать в controller


Ответ

Существует множество способов установки Twig-a. Самый простой и быстрый - это скачивание компонента с GitHub, после чего архив необходимо распаковать, и перекинуть каталог lib в папку с нашим проектом.
Ну а теперь давайте приступим к делу и рассмотрим структуру нашего небольшого проекта:
compilation_cache lib Twig templates base.html books.html index.php
Весь функционал, связанный с подключением и настройкой Twig-а, содержится в файле index.php. В папке templates мы будем хранить файлы шаблонов. В нашем случае, этих файлов 2: base.html с базовым html кодом и books.html с выводом списка книг. В каталоге compilation_cache будут помещаться PHP файлы, созданные Twig-ом для работы.
Итак, первое что нам необходимо сделать, так это подключить Twig:
require_once 'lib/Twig/Autoloader.php'; Twig_Autoloader::register();
После этого сообщаем шаблонизатору, где у нас хранятся файлы шаблонов. В качестве аргумента передаём путь к каталогу templates:
$loader = new Twig_Loader_Filesystem('templates');
Затем создаём объект шаблонизатора и указываем ещё несколько опций:
$twig = new Twig_Environment($loader, array( 'cache' => 'compilation_cache', 'auto_reload' => true ));
Параметру cache передаём путь к каталогу compilation_cache. Активируем опцию auto_reload, для того чтобы при обновлении страницы Twig заново обрабатывал шаблоны, и мы видели изменения. Если этого не сделать, то шаблонизатор просто закэширует страницы. Когда же работа над проектом будет завершена, эту опцию можно убрать, чтобы ваши страницы закэшировались и грузились ещё быстрее.
Для реализации нашего небольшого примера, возьмём список книг и сформируем массив вида ключ - значение:
$books = array( array('number' => 'Книга 1', 'title' => 'Гарри Поттер и философский камень', 'date' => '30.06.1997'), array('number' => 'Книга 2', 'title' => 'Гарри Поттер и Тайная комната', 'date' => '2.07.1998'), array('number' => 'Книга 3', 'title' => 'Гарри Поттер и узник Азкабана', 'date' => '8.07.1999'), array('number' => 'Книга 4', 'title' => 'Гарри Поттер и Кубок огня', 'date' => '8.07.2000'), array('number' => 'Книга 5', 'title' => 'Гарри Поттер и Орден Феникса', 'date' => '21.07.2003'), array('number' => 'Книга 6', 'title' => 'Гарри Поттер и Принц-полукровка', 'date' => '16.07.2005'), array('number' => 'Книга 7', 'title' => 'Гарри Поттер и Дары Смерти', 'date' => '21.07.2007') );
Для того чтобы передать данные в какой-то шаблон и вывести html результат, нам необходимо воспользоваться методом render(); В качестве первого аргумента передаём название файла шаблона, который будем выводить. В качестве второго -массив вида ключ - значение. В дальнейшем по заданным ключам мы будем получать доступ к нашим данным в самих шаблонах.
echo $twig->render('books.html', array('books' => $books));
Общий вид файла index.php
require_once 'lib/Twig/Autoloader.php'; Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('templates'); $twig = new Twig_Environment($loader, array( 'cache' => 'compilation_cache', 'auto_reload' => true ));
$books = array( array('number' => 'Книга 1', 'title' => 'Гарри Поттер и философский камень', 'date' => '30.06.1997'), array('number' => 'Книга 2', 'title' => 'Гарри Поттер и Тайная комната', 'date' => '2.07.1998'), array('number' => 'Книга 3', 'title' => 'Гарри Поттер и узник Азкабана', 'date' => '8.07.1999'), array('number' => 'Книга 4', 'title' => 'Гарри Поттер и Кубок огня', 'date' => '8.07.2000'), array('number' => 'Книга 5', 'title' => 'Гарри Поттер и Орден Феникса', 'date' => '21.07.2003'), array('number' => 'Книга 6', 'title' => 'Гарри Поттер и Принц-полукровка', 'date' => '16.07.2005'), array('number' => 'Книга 7', 'title' => 'Гарри Поттер и Дары Смерти', 'date' => '21.07.2007') );
echo $twig->render('books.html', array('books' => $books));
Настройка базового шаблона.
Базовый шаблон представляет собой обычный html документ со специальными вставками:
{% block title %}{% endblock %}

{% block content %} {% endblock %}


В нашем главном шаблоне мы прописываем 2 блока: title и content. Названия блоков выбираем сами. В последствии, в эти общие блоки мы будем внедрять характерную для дочерних страниц информацию.
Настройка шаблона вывода книг
Для начала в дочернем шаблоне нам необходимо указать шаблон родителя:
{% extends "base.html" %}
Далее в блок title запишем название дочерней страницы, которая обработается Twig-ом и вставится между тегами title в базовом шаблоне:
{% block title %}Серия романов о Гарри Поттере{% endblock %}
Затем, пишем содержание, которое внедрится в блок под названием content в базовом шаблоне:
{% block content %}

Серия романов о Гарри Поттере


{% for book in books %}
{{book.number}}. "{{book.title}}" - {{book.date}}
{% endfor %}
{% endblock %}
Тут же в цикле for (Twig for) мы проходимся по всем книгам, которые передали в данный шаблон с помощью записи $twig->render('books.html', array('books' => $books)); и для извлечения значений обращаемся к элементам массива по ключам: {{book.number}}, {{book.title}} и так далее. Таким образом, после срабатывания метода $twig->render('books.html', array('books' => $books)), Twig подгрузит шаблон books.html и сформирует html содержание. Далее он распознает, что books.html - это дочерний шаблон base.html, и поместит сформированное содержание в базовый шаблон. После всего этого Twig вернёт нам полноценную html страницу.

Почему scss так компилирует переменные?

Этот вопрос касается Icomoon в целом.
Не могу разобраться почему scss так компилит символы, но они работают, если в пути к шрифту указан не только шрифт, но и кэш шрифта.
Связанный вопрос: что это за кэш?
$icomoon-font-path: "fonts" !default; $icon-bell: "\e900"; $icon-like: "\e901"; $icon-paceholder: "\e902"; $icon-search: "\e903"; $icon-star: "\e904"; $icon-vision: "\e905"; $icon-vision-off: "\e906"; $icon-angle-left: "\e907"; $icon-angle-right: "\e908"; $icon-arrow-right: "\e909"; $icon-angle-bottom: "\e90a"; $icon-chat-angle-bottom: "\e90b"; $icon-chat-angle-top: "\e90c";
@import "variables"; @font-face { font-family: 'Icomoon'; src: url('#{$icomoon-font-path}/Icomoon.eot?r3waic'); src: url('#{$icomoon-font-path}/Icomoon.eot?r3waic#iefix') format('embedded-opentype'), url('#{$icomoon-font-path}/Icomoon.ttf?r3waic') format('truetype'), url('#{$icomoon-font-path}/Icomoon.woff?r3waic') format('woff'), url('#{$icomoon-font-path}/Icomoon.svg?r3waic#Icomoon') format('svg'); font-weight: normal; font-style: normal; } [class^="icon-"], [class*=" icon-"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'Icomoon' !important; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .icon-bell { &:before { content: $icon-bell; } } .icon-like { &:before { content: $icon-like; } } .icon-paceholder { &:before { content: $icon-paceholder; } } .icon-search { &:before { content: $icon-search; } } .icon-star { &:before { content: $icon-star; } } .icon-vision { &:before { content: $icon-vision; } } .icon-vision-off { &:before { content: $icon-vision-off; } } .icon-angle-left { &:before { content: $icon-angle-left; } } .icon-angle-right { &:before { content: $icon-angle-right; } } .icon-arrow-right { &:before { content: $icon-arrow-right; } } .icon-angle-bottom { &:before { content: $icon-angle-bottom; } } .icon-chat-angle-bottom { &:before { content: $icon-chat-angle-bottom; } } .icon-chat-angle-top { &:before { content: $icon-chat-angle-top; } }


Ответ

Sass при компиляции utf-8 юникод файлов - переводит подобные вашим последовательности в юникод-символы. Почему вы видите квадраты вместо символов в редакторе? Потому что в вашем моноширинном шрифте эти символы не отрисованы. Но они отрисованы в шрифте Icomoon, который подключается на сайте, и там в итоге символы корректно отображаются.
Резюмируя: Это нормальное поведение, и по поводу скомпилированных символов беспокоиться не стоит.
Однако, если вдруг ваши файлы хранятся в ASCII-кодировке - Sass все равно будет компилировать символы в них, хотя по логике - не должен. На гитхабе уже 3 года висит открытый тикет по теме. Можно почитать, но разумный способ решения - перевести свои стили в utf-8-кодировку.

Как изменить значение Resources.Strings?

Resources.Strings.Name= "";
Ошибка CS0200 Невозможно присвоить значение свойству или индексатору "Strings.Name" — доступ только для чтения.
///

/// Ищет локализованную строку, похожую на Name. /// internal static string Name{ get { return ResourceManager.GetString("Name", resourceCulture); } }


Ответ

Документация: https://msdn.microsoft.com/ru-ru/library/7k989cfy(v=vs.90).aspx#Anchor_2
При построении приложения Visual Studio вызывает средство resgen.exe для преобразования ресурсов приложения во внутренний класс с именем Resources. Этот класс находится в файле Resources.Designer.cs, который вложен в файл Resources.resx в Обозревателе решений. Класс Resources инкапсулирует все ресурсы проекта в статические свойства get только для чтения, что дает возможность получения строго-типизированных ресурсов во время выполнения.
Для пользовательских настроек и временных данных можно использовать массу других вариантов, от банального Application.Settings, до полноценных баз данных.

Векторная или растровая графика для 2D игры?

Делаю 2D игру на движке Unity, определился, что анимация для персонажей будет скелетной и реализовано с помощью расширения Anime2D, но вот где рисовать сами спрайты озадачился. Будет это растровое изображение(использование photoshop), или векторное.
Поэтому вопросы:
В каких случаях используют векторную, а в каких растровую? (например для персонажей рисуют векторную, а для фонов и декораций растровую) И какие самые популярные и лучшие инструменты для этого используются(например для растровой насколько я понял adobe photoshop мастхев), а для векторной графики? Есть разница в создании анимации при использовании растрового или векторной графики?


Ответ

Вообще юнити из коробки,на сколько мне извесно, не имеет возможности использовать векторную графику. А значит, предпочтительнее растовая, как поддерживаемая по дефолту.
Если расчитываешь что будут играть на больших расширениях экрана и не на мобилах) Векторная графика в любом случае будет более требовательна к железу. Тем более если работать со сторонними ассетами, которые не факт что написаны нормально. Как ни странно -- любой векторный редактор, формат которого поддерживает выбранный ассет юнити. Скорее всего файлы адоб Илюстратора будут поддерживатся. Понятия не имею. Не пробовал

Завершение процесса

Возможно ли завершить процесс через onBackPressed() ??
не получается так:
h = new Handler() { public void handleMessage(android.os.Message msg) { new RequestREFRESH().execute(API_URL); } };
System.out.println("Запускаю цикл обновления"); Thread t = new Thread(new Runnable() { public void run() {
for (int i = 1; i < 86400; i++)//86400-секунд в сутках { h.sendEmptyMessage(i); System.out.println("Запускаю функцию обновления"); try { System.out.println("Приостанавливаю поток на 5 секунд"); Thread.sleep(5000); //Приостанавливает поток на 5 секунд } catch (InterruptedException e) { System.out.println("Ошибка задержки среды"); e.printStackTrace(); } }
} }); t.start();
@Override public void onBackPressed() {
if (t != null) { Thread dummy = t; t = null; dummy.interrupt(); }
}
переделал так:
h = new Handler() { public void handleMessage(android.os.Message msg) { new RequestREFRESH().execute(API_URL); } };
System.out.println("Запускаю цикл обновления"); t = new Thread(new Runnable() { public void run() {
try { for (int i = 1; i < 86400; i++)//86400-секунд в сутках { if (!t.isInterrupted()) { h.sendEmptyMessage(i); System.out.println("Запускаю функцию обновления");
try { System.out.println("Приостанавливаю поток на 5 секунд"); Thread.sleep(5000); //Приостанавливает поток на 5 секунд } catch (InterruptedException e) { System.out.println("Ошибка задержки среды"); e.printStackTrace(); }
} else { throw new InterruptedException(); } } } catch (InterruptedException e) { System.out.println("Thread is interrupted"); }
} }); t.start();
@Override public void onBackPressed() {
if (t != null) { Thread dummy = t; t = null; dummy.interrupt(); }
}
получил ошибку - FATAL EXCEPTION: Thread-83


Ответ

У Вас после interrupt() должен сработать блок catch (правда не сразу, конечно). Добавьте в него break, чтобы выйти из цикла и корректно завершить работу потока.
Также корректно было бы добавить в условие цикла !isInterrupted(), помимо условия i < 86400.
ОБНОВЛЕНО
Переделали Вы странно. Достаточно было в блок catch после вывода e.printStackTrace() вписать команду break, а также изменить условие в цикле на i < 86400 && !isInterrupted()
Еще один try-catch и выброс своего exception бессмысленны.