org.apache.jasper.JasperException: Абсолютный uri: http://java.sun.com/jstl/core не может быть разрешен в файле web.xml или jar развернутый с этим приложением
blockquote>Этот URI для JSTL 1.0, но вы на самом деле используете JSTL 1.2, который использует URI с дополнительным
/jsp
путем (поскольку JSTL, который изобрел EL-выражения, поскольку версия 1.1 интегрирована как часть JSP для совместного использования / повторного использования EL-логики в простом JSP).Итак, исправьте URI taglib соответственно:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Дальше POM также определяет реализацию Apache JSTL 1.1 через
taglibs:standard
. Это необязательно и даже опасно, если у вас уже есть JSTL 1.2 API + impl, связанный черезjavax.servlet:jstl
, потому что 1.1 и 1.2, очевидно, конфликтуют друг с другом. Только одна из следующих зависимостей JSTL 1.2 должна сделать это, чтобы JSTL был установлен в вашем веб-приложении, ориентированном на Tomcat (не устанавливайтена
provided
, поскольку Tomcat на самом деле не предоставляет его в поле!):
javax.servlet jstl 1.2 Пользователи, не являющиеся членами Maven, могут добиться того же, отбросив единственный файл jstl-1.2.jar в папке
/WEB-INF/lib
проекта веб-приложения (не отбрасывайте standard.jar или любые свободные .tld-файлы там!).Если вы на самом деле используете обычный Java EE-сервер, такой как WildFly, Payara и т. д. вместо barebones servletcontainer, таких как Tomcat, Jetty и т. д. то вам не нужно явно устанавливать JSTL. Обычные серверы Java EE уже предоставляют JSTL из коробки. Другими словами, вам не нужно добавлять JSTL в
pom.xml
и не удалять файлы JAR / TLD в webapp. Исключительно достаточноprovided
координаты Java EE:
javax javaee-api provided Далее вы также должны убедиться, что ваш
web.xml
объявлен как совместимый не менее Servlet 2.4 и, следовательно, не как Сервл 2.3 или старше. В противном случае EL-выражения внутри тегов JSTL, в свою очередь, не сработают. Выберите самую высокую версию, соответствующую вашему целевому контейнеру, и убедитесь, что у вас нетв любом месте вашего
web.xml
. Вот пример совместимости с сервлетами 4.0 (Tomcat 9):
См. Также:
- Документация по ключевому тегу JSTL для ключевого слова (для правильного taglib URI)
- Информационная страница тега JSTL (для ссылок загрузки JSTL и примеров
web.xml
)
Более новые версии повышение:: поток имеет блокировки чтения-записи (1.35.0 и позже, по-видимому, предыдущие версии не работали правильно).
Они имеют имена shared_lock
, unique_lock
, и upgrade_lock
и воздействуют на shared_mutex
.
Используя стандарт предварительно протестированный, предварительно созданный материал всегда хорош (например, Повышение как другой предложенный ответ), но это - что-то, что это не слишком твердо для создания самостоятельно. Вот немая небольшая реализация, вытащил из моего проекта:
#include <pthread.h>
struct rwlock {
pthread_mutex_t lock;
pthread_cond_t read, write;
unsigned readers, writers, read_waiters, write_waiters;
};
void reader_lock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
if (self->writers || self->write_waiters) {
self->read_waiters++;
do pthread_cond_wait(&self->read, &self->lock);
while (self->writers || self->write_waiters);
self->read_waiters--;
}
self->readers++;
pthread_mutex_unlock(&self->lock);
}
void reader_unlock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
self->readers--;
if (self->write_waiters)
pthread_cond_signal(&self->write);
pthread_mutex_unlock(&self->lock);
}
void writer_lock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
if (self->readers || self->writers) {
self->write_waiters++;
do pthread_cond_wait(&self->write, &self->lock);
while (self->readers || self->writers);
self->write_waiters--;
}
self->writers = 1;
pthread_mutex_unlock(&self->lock);
}
void writer_unlock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
self->writers = 0;
if (self->write_waiters)
pthread_cond_signal(&self->write);
else if (self->read_waiters)
pthread_cond_broadcast(&self->read);
pthread_mutex_unlock(&self->lock);
}
void rwlock_init(struct rwlock *self) {
self->readers = self->writers = self->read_waiters = self->write_waiters = 0;
pthread_mutex_init(&self->lock, NULL);
pthread_cond_init(&self->read, NULL);
pthread_cond_init(&self->write, NULL);
}
pthreads
не действительно бывший собственный Windows, но общее представление здесь. Эта реализация немного склоняется к писателям (орда писателей может исчерпать ресурсы читатели неограниченно долго); просто измените writer_unlock
, если Вы быть бы баланс быть наоборот.
Да, это - C и не C++. Перевод является осуществлением, оставленным читателю.
Greg Rogers указал, что стандарт POSIX действительно определяет pthread_rwlock_*
. Это не помогает, если Вы не имеете pthreads
, но это размешало мой ум в запоминание: Pthreads-w32 должен работать! Вместо того, чтобы портировать этот код на не - pthreads
для Вашего собственного использования, просто еще используйте Pthreads-w32 в Windows и собственный компонент pthreads
везде.
Независимо от того, что Вы решаете использовать, сравнить Вашей рабочей нагрузки с простыми блокировками, поскольку блокировки чтения-записи имеют тенденцию быть 3-40x медленнее, чем простое взаимное исключение, когда нет никакой конкуренции.
Вот некоторая ссылка
Редактирование: ссылка MSDN Magazine больше не доступна. Статья CodeProject теперь доступна на https://www.codeproject.com/Articles/32685/Testing-reader-writer-locks и подводит итог его довольно приятно. Также я нашел новую ссылку MSDN приблизительно Составные Объекты синхронизации .
существует , статья о читателе-устройстве записи соединяет MSDN, который представляет некоторые реализации их. Это также представляет блокировку читателя/устройства записи Slim, синхронизация ядра, примитивная начатый с Vista. Существует также статья CodeProject о сравнении различных реализаций (включая статьи MSDN).
Повышение. Поток имеет, так как выпуск 1.35.0 уже поддерживает блокировки читателя-писателя. Хорошая вещь об этом состоит в том, что реализация является значительно межплатформенной, рецензируемой, и на самом деле ссылочная реализация для предстоящего C++ 0x стандарт .
Intel Thread Building Blocks также обеспечивает несколько rw_lock вариантов:
http://www.threadingbuildingblocks.org/
у Них есть spin_rw_mutex в течение очень коротких периодов конкуренции и queueing_rw_mutex в течение более длительных периодов конкуренции. Первый может использоваться в особенно производительности чувствительный код. Последний более сопоставим в производительности с обеспеченным Повышением. Поток или непосредственно использующий pthreads. Но профиль для проверки, какой является победой для схем доступа.
Вы могли скопировать Sun, превосходный ReentrantReadWriteLock. Это включает функции, такие как дополнительная справедливость, понижение блокировки, и конечно повторная входимость.
Да это находится в Java, но можно легко считать и транспонировать его к C++, даже если Вы не знаете Java. Документация, с которой я связался, содержит все поведенческие свойства этой реализации, таким образом, можно удостовериться, что это делает то, что Вы хотите.
, Если ничто иное, это - руководство.
Я могу рекомендовать библиотека ACE , который обеспечивает множество блокировки механизмов и портирован на различные платформы.
В зависимости от граничных условий Вашей проблемы, можно найти следующие классы полезными:
ACE_RW_Process_Mutex
ACE_Write_Guard
и ACE_Read_Guard
ACE_Condition