Самое простое решение:
Вместо использования:
var funcs = [];
for(var i =0; i<3; i++){
funcs[i] = function(){
alert(i);
}
}
for(var j =0; j<3; j++){
funcs[j]();
}
, который предупреждает «2», в 3 раза. Это связано с тем, что анонимные функции, созданные в цикле for, имеют одно и то же закрытие, а в этом закрытии значение i
одинаково. Используйте это, чтобы предотвратить совместное закрытие:
var funcs = [];
for(var new_i =0; new_i<3; new_i++){
(function(i){
funcs[i] = function(){
alert(i);
}
})(new_i);
}
for(var j =0; j<3; j++){
funcs[j]();
}
Идея этого заключается в том, что инкапсуляция всего тела цикла for с помощью IIFE (выражение с выражением немедленного вызова) и передача new_i
в качестве параметра и зафиксировать его как i
. Поскольку анонимная функция выполняется немедленно, значение i
отличается для каждой функции, определенной внутри анонимной функции.
Это решение похоже на любую проблему, так как оно потребует минимальных изменений в исходном коде, страдающем из этого вопроса. Фактически, это по дизайну, это не должно быть проблемой вообще!
Если вы заглянете внутрь флага jersey-media-json-jackson
, вы увидите файл
META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
. Содержимое этого файла должно быть единственным полным именем класса, который реализует имя файла, а именно
org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable
Этот файл используется механизмом автообнаружения для Джерси для автоматической регистрации функций без необходимости их явного их регистрации. Вкратце, как это работает, все модули / банки Джерси, у которых есть компоненты, которые должны быть автоматически зарегистрированы, должны иметь вышеупомянутый файл, расположенный в банке, причем содержимое является именем (именами) компонента с возможностью автоматического обнаружения. Затем Джерси будет использовать шаблон загрузчика Service Loader , чтобы загрузить классы, указанные в файле, и зарегистрировать их.
Проблема, которая возникает при создании uber-банок, заключается в том, что вы можете иметь только один копия файла, у вас не может быть дубликатов. Итак, что, если у нас есть несколько банок с вышеупомянутым файлом? Ну, только один из этих файлов будет включен в банку uber. Который из? Кто знает, но есть только один счастливый победитель. Таким образом, для остальных банок их механизм автоматического обнаружения никогда не срабатывает. Это относится к вашей функции Джексона, где автообнаружение регистрирует JacksonFeature
. Вы можете попытаться явно зарегистрировать свое приложение, и вы увидите, что он теперь работает.
Но как насчет других банок / модулей, которые могут иметь этот файл? Именно по этой причине при создании uber jars вы должны использовать maven-shade-plugin . Что этот плагин позволяет вам сделать, объединить содержимое файлов, чтобы все обнаруживаемые объекты включались в этот один файл. Ниже приведен пример использования
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.YourApp</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
. Этот пример был фактически взят из Начало работы Dropwizard . Вы можете проверить это для дальнейшего объяснения. Основная часть проблемы - ServicesResorceTransformer
, которая объединяет файлы служб.