Throwable
+1

У нас пострадали в основном крупные компании.
http://www.elmundo.es/tecnologia/2017/05/12/59158a8ce5fdea194f8b4616.html


В пятницу их работники получали уведомление отключить все персональные компьютеры до выяснения обстоятельств, что практически парализовало работу многих служб. Вобщем-то это говорит о низком уровне корпоративной политики безопасности.

Throwable
+1
Вы хотите сказать в том же IBM отдельно сидят люди, которые участвуют в JCP и отдельно те, кто пишет софт и причем первые не общаются со вторыми? Не проблема ли это IBM

Это проблема не только IBM, а всех крупных компаний, где есть жесткое разделение труда. И да, специалисты, участвующие в JCP, возможно не писали реальный бизнес-код уже лет десять или больше.


Поэтому еще год назад от них были призывы "если вы видите какие-то проблемы у вашей библиотеки/фреймворка при переходе на Jigsaw — напишите нам!".

Это когда еще мало-мальски стабильной девятки не было? Есть очень много решений, базирующихся на classpath. SLF4J использует classpath для поиска бэкенда для логгинга и настроек. Чтобы это сработало в модульной среде, библиотека должна быть изменена концептуально. И все остальные библиотеки, использующие SLF4J, будут ждать, пока мейнтейнеры соизволят выпустить его модульную версию, а также модульную версию всех своих зависимостей. И так с каждыми библиотеками, фреймворками и тулзами для сборки, тестинга и, наконец, продуктами. Период перехода может затянуться лет на 5 или больше, и все это время придется поддерживать две версии. В итоге экосистема сплитанется на две — модульную и classpath-ную.


А теперь главный вопрос: в чем реальный профит модульности?

Throwable
+3

Очевидно, это разные люди — те, кто пишет спецификации и те, кто разрабатывает софт. Когда появился более-менее стабильный кандидат девятки, компании попробовали портировать свой стек под новую платформу и во многом обломались. Я не уверен, что изначально даже был сделан анализ более-менее распространенных библиотек, фрекмворков и тулзов на предмет насколько их затронет изменение и какие могут быть методы решения. В любом случае, выход девятки — это будет глобальный сплит всей экосистемы.

Throwable
0

Наконец-то в браузере появятся нормальные лейауты! FlexBox вместе с GridLayout покрывают практически всю необходимость разметки в приложениях.
А вообще, как-то странно: именно производители "того самого браузера" изначально предложили и пилили спецификацию GridLayout, теперь же хуже всех ее поддерживают.

Throwable
+6

Дааа! Респект за упоминание Ultimae Records!!! В свое время они выпускали годную серию сборников псайбиента под названием Fahrenheit Project. Рекомендую всем! Просто офигительное звучание и очень интересные наработки! Из Solar Fields очень нравится его первый альбом Reflective Frequencies. Упомянутые Asura больше работает в стиле Slow Trance, а вот их бывший музыкант Aes Dana делает чистый dark ambient. Также вместе с Solar Fields они запилили неплохой проект H.U.V.A. Networks на том же Ultimae но по мне, так он слишком атмосферный — люблю тяжелые драм секции. Вобщем, лейбл Ultimae Records — номер один для любителей псайбиента.


Еще тащился от проекта Vibrasphere — в основном они работают в PsyTrance, но у них есть прям сказочные псайбиентные треки. Жаль, что закрылись.

Throwable
0

Да, согласен. В этом случае OSGi действительно помогает как единая платформа для деплоя, если имеется большое число более-менее независимых модулей.


Я сам не большой фанат контейнеров и микросервисов, поскольку в самой Java уже встроены неплохие средства виртуализации. Контейнеры сильно усложняют архитектуру и деплой и должны применяться только там, где это действительно необходимо, а не по зову моды. Также не имеет смысла искусственно дробить приложение на микросервисы, если у него единый функционал и цикл разработки.

Throwable
0

А вот интересно, как вы все это пускаете в devmode? По стандартной схеме build-pack-deploy? Или плагин какой используете?
И мне кажется, не совсем аргументирована модульность приложения. Внутренне — да, имеет смысл для кода и тестов. Но с точки зрения деплоя лучше иметь единственный артефакт, нежели груду джарников.
Если необходима модульность, по-моему лучше будет разбить приложение на микросервисы и стартовать каждый в отдельной JVM/контейнере, как это делается сейчас. Единственный сценарий, который приходит на ум — платформа для деплоя различных приложений и микросервисов с разным циклом разработки. Что-то типа ESB или AppServer. Фактически там он в осносном и используется.

Throwable
+2

Я не совсем согласен с такой точкой зрения. Иметь свой корпоративный репозиторий в команде это, конечно же, хорошо и правильно. Но я всегда следую принципу, что проект должен уметь собираться всегда и везде, без лишних геморроев. Локальный репозиторий проекта — разумное решение, когда тебе нужен всего лишь какой-нибудь пропиетарный драйвер. Это делает сборку проекта автономной и независимой от окружения. Maven Wrapper при этом еще отлично помогает.

Throwable
0

Есть одна проблема с локальным репозиторием — для мультимодульного проекта придется корректировать путь к нему в каждом pom.xml, так как project.badedir будет у каждого модуля свой.

Throwable
+1

По поводу IT-рекрутинга в блоге у yegor256 понравилась фраза: "You're Just the Mayonnaise in a Bad Sandwich"

Throwable
+2

У меня сложилось такое впечатление, что сейчас под трендом "микросервисы" пытаются втюхать Spring Boot, Rest и иногда каким-то образом припаять Docker. И если посмотреть в Google Trends, то собственно так оно и есть. То есть чтобы в мозгу разработчика четко отложилось: java-приложения, оказывается, можно разрабатывать без контейнера, но для этого нужен Spring Boot, который нам даст Rest. И это теперь называется микросервисами.


Тем не менее, 10 лет назад в эпоху засилия SOA и JavaEE, когдя я писал что-то вроде:


@WebService
public class AddService {
    @WebMethod
    public int add(int a, int b) {
        return a+b;
    }
    public static void main(String[] args ){
        Endpoint.publish("http://0.0.0.0:1234/AddService", new AddService());
    }
}

не было подходящего названия для этого. Люди недоумевали: если это java-приложение, то где интерфейс с кнопочками? Если это веб-приложение, то где сервер приложений, куда оно должно деплоиться? Здесь даже не было более-менее знакомого слова "Spring". И вплоть до того, что клиенты отказывались принимать работу, поскольку не знали каким словом это назвать (мой клиент все-таки придумал название — "тамагочи"))).


Теперь же я любое решение, которое не требует контейнера, я с гордосью называю "микросервис" и вопросов не возникает.

Throwable
+2

Практическая полезность была бы кстати, если бы JVM умела бы делать быстрый hot-restart: прибиваются все треды, освобождаются все системные ресурсы, но при этом оставлялся бы PermGen с классами, сгенеренной статистикой выполнения и предкомпилированным кодом.


Предлагаю следующий этап эволюции GC и архитектуры приложений: не собирать мусор, пока не заполнится вся память, затем вызвать специальный OutOfMemory-хандлер у тредов, у которых он зарегистрирован, после чего начать полную сборку мусора.


Что это даст? Процессинговые треды, имеющие OutOfMemory хандлер смогут обработать ситуацию: закрыть ресурсы, вернуть ошибку клиенту, сообщить в кластер, что нода отвалилась, и при необходимости рестартнуть после сборки мусора. Чтобы при вызове хандлеров не было повторного OutOfMemory вся аллокация ведется в отдельно зарезервированной области.


Таким образом можно реализовать быстрый перезапуск процессинга без реальной необходимости перезапуска системы.

Throwable
+1

Де-факто в Java есть проперти. И описаны они в стандарте JavaBeans при помощи геттеров и сеттеров. И многие сторонние фреймворки и библиотеки не привыкли работать напрямую с полями, а вместо этого делают интроспекцию пропертей.


В общем случае некорректно думать о пропертях как о полях для хранения данных. Пропертя позволяют скрыть логику хранения данных и добавить дополнительный функционал как валидация значений, lazy-инициализации, связанные значения, события, etc. Ну и естественно, сделовать принципам ООП и переопределять поведение при наследовании.


А в DTO геттеры и сеттеры действительно не нужны. Я по возможности стараюсь их делать immutable со всеми полями public final. Есть неплохой проект на этот счет Immutables.org.

Throwable
0

Вещь, которая изо дня в день бесит в java — геттеры сеттеры. Пусть сделают человечный property в качестве сахара. Дабы не быть голословным:


class Test {
  private String vasya;
  public String getVasya() { return this.vasya;}
  public void setVasya(String vasya) { this.vasya = vasya;}
}

Итак, для описания одного лишь свойства vasya мы повторили это слово 7 раз в общей сложности затратив 17 слов! Думаете все? Нет. Добавьте еще javadoc-описание свойства к гетеру и продублируете его же в сеттере.


Хочется некий алиас который бы генерировал для свойства поле, геттер и сеттер, а в интерфейсах только геттер и сеттер, плюс который бы позволял в коде напрямую обращаться к property. При этом бы вся семантика с override сохранялась.

Throwable
0

В Entity финальное поле, может, и не нужно. А вот при создании immutable-объектов, если используется сериализация отличная от Java, требуется определить пустой конструктор, где нужно инициализировать все final nonnull-поля (кстати, забыл в примере пометить как поле nonnull) дефолтными значениями. Если раньше все прокатывало с null-ами, то теперь требуется определить некие "пустые" объекты для каждого из полей.


Я считаю, что нарушение контракта — это как раз вставка проверок на nonnull в рантайме, т.к. изначально эта аннотация планировалась исключително для warning-ов при компиляции. И с @SuppressWarnings код должен компилироваться и работать корректно.

Throwable
0

Очень интересно! Как я понял, MavenClassLoader по дефолту автоматически загружает все зависимости в один модуль. Если я хочу изолировать некоторые зависимости в отдельные модули, я их загружаю отдельно, а затем использую вариант с parent-ом — зависимости заново загружаться не будут?

Throwable
–2

Юмор понятен. Но вот реальный способ платить меньше.
Выдавайте часть зарплаты различными социальными бонусами: карты на обеды, проезд в общественном транспорте, мед. страховка, абонемент в спортзал, etc… Вроде как для работника сумма та же, а вы экономите на налогах (НДС, подоходный).

Throwable
0

Не подскажете, кто теперь насильно вставляет проверки на null для @Nonnull параметров? Это компилятор или IDE? Сейчас апдейтнулся и сломалась половина тестов с ошибкой:


Caused by: java.lang.IllegalArgumentException: Argument for @Nonnull parameter 'correlationId' of services/storage/CorrelationStorage$Correlation. must not be null
at services.storage.CorrelationStorage$Correlation.$$$reportNull$$$0(CorrelationStorage.java)

Просто есть куча immutable классов с публичным конструктором и параметрами @Nonnull. Чтобы работали всякие JPA и сериализаторы, добавляю приватный конструктор по умолчанию, который вызывает публичный с нулами:

class Bean {
public final String param;
public Bean(@Nonnull String param) {this.param = param;}
@SuppressWarnings("all")
private Bean() {this(null);}
}

До 16.3 все работало. Где отключается?

Throwable
+2
Оговоримся, что Rabbit MQ у себя в production мы не используем из-за невозможности его работы с XA.

Вместе с тем вы используете Rest, который вообще как бы не транзакционный. Странная мотивация.


Данное решение так же устраняет проблему невозможности отката транзакции при работе с внешними сервисами. Никакой вызов не пройдет дважды — обработка начинается именно с того шага, на котором произошел сбой.

Вопрос на засыпку: что делать, если мой любимый http вернул timeout? Rest обработал изменения или нет?
В вашей схеме каждый Rest-сервис должен локально записывать транзакции и автоматически игнорировать их при повторном вызове.

Throwable
+2

Знакомо, только в моем случае я пришел очень далеко не Junior-ом, а эти люди без надлежащего профессионального уровня, мне указывали что и как я должен делать.


Есть три пути: потихоньку неспеша подыскивать новое место, либо втереться в доверие к кому-нибудь из верхушки и лизать ему задницу в надежде, что тебя примут, либо третий вариант — втихаря вкалывать, не гнушаться лишних заданий, проявлять инициативу, пытаться закольцевать как можно кода и решений на себя, помогать своим коллегам, пытаться выходить напрямую на контакт с клиентами. В определенный момент ты увидишь, как к тебе начнут прислушиваться как твои коллеги, так и "сверху". Помни, что ты развиваешься, а твоя "верхушка" нет, и скоро станет балластом.

Throwable
0
Более, чем можно себе представить.Если мы хотим при помощи корутин определять долгоиграющие StateMachine-ы, то состояние после suspend-а хотелось бы персистить, а перед resume-ом восстанавливать. Юзкейсов десятки, от всяких WebFlow, BPM до high availability.
Throwable
0
Там пока корутины не сериализуемы. Обещают подумать над темой в будущих релизах.
Throwable
0
Файберы — это не совсем континуации, это suspendable threads. Для континуаций не нужны никакие экзекьюторы. Весь экзекьютор — это простой цикл:
Continuation d = Continuation.startWith(new MySuspendable());
while(d!=null) {
d = Continuation.continueWith(d);
}
т.е. фактически выполняются вручную, что дает полный контроль выполнения, и что как бы и требуется для задачи: при необходимости можно сериализовать и сохранить состояние в БД, при получении внешнего месседжа загрузить континуацию и продолжить.

А поскольку файберы подобно тредам должны выполняться автоматически, им нужен внешний шедулер, который будет контролировать их выполнение. И чтобы свести случай к предыдущему, нужно писать свой шедулер. А в API квазара это как бы не совсем предусмотрено.
Throwable
+1
В свое время искал решение для написания логики бизнес процессов на Java, что есть по сути обычная StateMachine. Хотелось бы, чтобы flow был написан натуральными конструкциями, но при этом код был асинхронный. Необходимо было: а) корутины, б) сериализация состояния, в) возможность полного перехватывания после suspend. Ничего не нашел, что бы могло бы на 100% удовлетворить.

На мой взгляд основное неудобство Quasar в том, что выполнение файберов сильно завязано на FiberScheduler (которых фреймворк предоставляет два: FiberExecutorScheduler и FiberThreadPoolScheduler). Вся магия выполнения лежит в нем. Если я хочу кастомно выполнять файбер после прерывания Continuation.continueWith©, как это делается в javaflow, то придется писать свой Scheduler.

Другое основное неудобство всех корутинных библиотек на Java — жесткое трюкачество на уровне байткода: требуется настройка тулзов и добавление агентов в рантайм. Все это сильно усложняет архитектуру, дебагинг и тесты.

Так что лучше подождем, пока официально запилят корутины Kotlin-е.

P.S. Добавьте еще одну библиотеку, которая на самый момент наиболее продвинутая — https://github.com/offbynull/coroutines
Работает с Java8. Основной недостаток — приходится въявную таскать во все suspendable-методы объект Continuation.
Throwable
+2
Приложение собирается при помощи Maven/Gradle и экспортирует все свои зависимости. JRE не таскаем — это уже реквизит клиента.
Для запуска используем «Yet Another Java Service Wrapper». На Java корректно упавшее приложение в случае исключительной ситуации — это большая редкость. Чаще всего процесс висит, но не обрабатывает запросы. Поэтому всегда приходится делать велосипеды типа Watchdog-ов и интегрировать их с YAJSW.
Про логи не понял. Однозначно slf4j+logback. Для кластерного приложения лучше поднять logging server и сбрасывать туда.
Артефакты для деплоя хранятся в центральном репозитории, который есть SVN (не смейтесь) со всеми своими версиями, ветками, экономией места, etc… Деплой делается простой командой svn update. Более того, она иногда стоит в скрипте (пере)запуска.

Теперь что огорчает:
— Разрабатываю на Windows. Пускать VirtualBox, чтобы поднять контейнер, чтобы просто сделать билд приложению по-моему накладно. На данный момент билд приложения можно сделать на любой машине с JDK (спасибо Maven wrapper).
— Упс. А у клиента Solaris :( И вообще они сказали, что это их инфраструктура и они хотят контролировать и мониторить что и как на ней вертится.
— Меппинг портов из контейнера сильно усложняет использование извне таких API как JMX, и делает невозможным использование RMI. А также усложняет конфигурацию многих распределенных систем, использующих multicast протокол для service discovery.
— И вообще service discovery в docker — отдельная и достаточно нетривиальная тема. Например уже так просто не запустить в контейнерах приложение с embedded Zookeeper или Hazelcast.

Так что не все так однозначно.
Throwable
0

Я все-равно не услышал убедительной причины для использования Docker с Java. Docker в первую очередь решает проблему с нативными приложениями, которые требуют установки, конфигурирования и кучи зависимостей. Чтобы не возиться со всем этим, приложения изолируют в отдельный контейнер, в котором есть все необходимое. А JVM сама по себе уже достаточно неплохо виртуализирована. Поэтому многие использует Docker только как некое средство упаковки и доставки своих приложений — некий супер-JAR, при этом не имея реальной необходимости в средствах виртуализации.


Так что призыв паковать свои Java-микросервисы в Docker — это скорей как раз дань моде.

Throwable
+2

Фреймворк — это набор готовых шаблонов для решения определенного круга задач, который как правило базируется на определенной архитектурной парадигме (DI + IoC, Actors, Reactive, FP, etc...). Фреймворк позволяет девелоперу среднего уровня быстро бутстрапить типовые приложения без вникания в суть дела, просто копипастив код из примеров, а также предотвращает появление в коде слишком бурной фантазии новичка.


Упрощает ли фреймворк разработку — вопрос неоднозначный. Да, если Вы досконально его изучили, умеете им пользоваться, понимаете как он работает внутри, знаете все его ограничения, и грамотно обходите возможные грабли. Однозначно нет, если Вы находитесь в процессе его изучения, параллельно используя его в своем проекте. В этом случае разработка превращается в постоянное гугление и вопросы на форумах "как сделать как мне надо при помощи этого фреймворка".

Throwable
0

У нас вот очень жесткие требования клиента по стандартизации, поэтому заставляют нас, несчастных, сидеть на голом JEE. Даже завернуть в Spring не дают. За последние 10 лет столько настрадавшись при разработке JEE и всевозможных аккуратно расставленных граблей, что у меня единственное желание — чтоб он поскорее, наконец, сдох, ибо суть тормоз в разработке и зло в чистом виде.

Throwable
+1
Один и тот же код работает на нескольких Java EE 7-серверах без каких-либо дополнительных настроек

Человек, однако, лукавит, не стесняясь. Все дополнительные настройки (DataSources, JMS Connection Factories, аутентификацию, etc...) придется делать ручками для каждого сервера по-своему. Ну и как бы дополнительные дескрипторы тоже приходится добавлять, начиная от меппинга jndi, если у вас не "hello world". В стандарте задуман только неинтересный джентльменский набор фич, все остальное — vendor-specific расширения. Процесс разработка просто ужасен. Единственно удобоваримый вариант — обернуть весь проект в Spring.

Throwable
0

Пункт 2 порождает глобальные проблемы в совместимости.


Во-первых, это должно нарушить работу кучи библиотек и API. Пример:


JAXBContext jc = JAXBContext.newInstance("com.acme.foo");

JAXBContext лежит модуле в java.xml.bind, но доменные классы в com.acme.foo. То есть классы из com.acme.foo должны быть доступны модулю java.xml.bind, даже если он не импортирует модуль com.acme.foo.


Во-вторых, не позволяет простым способом "патчить" сторонние библиотеки, просто переписав класс в том же пакете. Не понятно, возможен ли будет по желанию "полный" импорт библиотеки со всеми ее приватными классами.


В-третьих, ни слова об экспортировании ресурсов: ClassLoader.getResource(). Если ресурсы доступны только текущему модулю, то это сломает огромное количество библиотек, в том числе java.util.ServiceLoader. Кстати, тему сервисов jigsaw вообще обходит стороной, тогда как в OSGi это центральная фишка.


Ну и в-четвертых, приватные классы модулей могут вылезать наружу как содержимое других объектов. Самый простой пример: exception chain, который в getCause() будет содержать внутренний эксепшн модуля или его транзитивных зависимостей. Как будет контролироваться доступ к этим классам — не понятно.


Вобщем, вопросов много, а вразумительных ответов по тому как работает модульность в jigsaw нет.

Throwable
0

Никаких. Если смотреть по аналогии кто пользует OSGi, то это достаточно узкоспециализированная область контейнеров и серверов апликаций. Jigsaw не решает многих проблем, типа версионирования, динамической подгрузки/выгрузки, активации/деакцивации модуля, etc..., что уже умеет OSGi. Например, Jigsaw не умеет из коробки управлять в рантайме разными транзитивными версиями одного модуля (хотя это может быть допилено вручную).
Модульность должна широко быть принята разработчиками билд тулзов и библиотек. Я думаю, этого не случится, потому как выигрыш очень сомнительный, а зартаты огромны.

Throwable
+7

Будем надеяться, что не Министерство Правды...

Throwable
0

Если Вы заметите, в IT подобное часто бывает. Применительно практически к любым технологиям: всегда найдется более изящный, но менее аналог.

Throwable
0

1) Да, мой косяк. Но почему-то в обоих случаях Regex.toString() возвращает одну и ту же строку.
2) Возможно. Я сильно не разбирался — не было времени. Парсилось около 50 файлов по 10Мб каждый. Зависание происходило спонтанно, каждый раз в новом месте, иногда даже прокатывало без зависаний. Но тред именно в read-е сидел. Странно.

Throwable
+2
val MSG = "Async service invocation: ISigresPartner Interface=INT.SIGRES.PSSBA.001 #_PI:90030156.2de27eff.e6df58f5.71524441"
// Java Regexp
val invokeMatcher = Pattern.compile(
        """.*:\s+([A-Za-z0-9\._-]+)\s+Interface=([A-Za-z0-9\._\-]+).+#(.+)""")
val match = invokeMatcher.matcher(MSG)
println(match.find())
// -> true
// Kotlin
println(Regex.fromLiteral(""".*:\s+([A-Za-z0-9\._-]+)\s+Interface=([A-Za-z0-9\._-]+).+#(.+)""").matches(MSG))
// -> false
println(Regex.fromLiteral(""".*:\s+([A-Za-z0-9\._-]+)\s+Interface=([A-Za-z0-9\._-]+).+#(.+)""").find(MSG))
// -> null

Regex 100% правильный, можете проверить на regex101.com.


    val files = File(logDir).listFiles {
        dif, name -> name.startsWith("SystemOut") && name.endsWith(".log")
    }.asList().sortedBy { if (it.name == "SystemOut.log") "Z" else it.name }

    files.forEach { file ->
        file.forEachLine { line ->
            // ...
        }
    }

Зависает. Но не на процессинге линии, а на чтении.
Throwable
+1

Неделю назад нужно было написать простой парсер логов одного приложения, ничего особенного. Попробовал Котлин. В итоге: Regex matcher не работает, а File.forEachLine мистически виснет. Заменил все джавовскими аналогами Pattern.compile/Matcher и BufferedReader. Фигня конечно, но как-то стремно, ибо чревато на ровном месте геморроем.

Throwable
+2

Просто ассоциация, идея чем-то напомнила Интерстеллар:
image

Throwable
+1
Лично мне тоже не совсем понятна политика Oracle по поводу Java EE. Очень интересно было бы послушать их комментарии. Если вы где-то их встречали, поделитесь пожалуйста ссылкой.


Вообще странная реакция от Oracle, у которого огромное количество продуктов завязано на Weblogic-е. С другой стороны, я считаю идею забить на JavaEE 100% правильной, т.к. технология совершенно не соответствует современным запросам. (p.s. больше 10 лет занимаюсь разработкой на JavaEE).
2.3. (Не) используйте assert!


Как уже много где писалось, assert хорош для повышения читаемости кода, когда валидность значений неясна из контекста. Assert объясняет, что конкретное условие в данном месте гарантируется и что дополнительные проверки не требуются.
Throwable
0
По-моему, большая часть взаимного непонимания в комментариях к этой статье связана с тем, что зачастую никакого такого отдельного «специального человека» попросту нет.

Более того, если такой человек есть, то он заведомо лишний в компании. Он не разработчик, поэтому плохо знает детали системы, он также не бизнес аналист, поэтому также не може предложить собственное решение или инициативу клиенту.
Вот типичная работа такого человека:



Поэтому все современные методики разработки пытаются уменьшить число ступеней в иерархии разработки, сделать структуру более плоской и прозрачной. Обязанности "software consultant" ложатся на team lead-а, который суть есть разработчик.

Throwable
+2
А чем, по-Вашему, занимался кандидат, как не сбором "бОльшегом количества данных о целевой задаче и области ее применения"?

Надменно демонстрировал важность своей работы и ценность своих знаний.


Первым вопросом должен быть не "что вы подразумеваете под вашей просьбой?", а "для чего вам это нужно?", "где вы это будете использовать?", "для какой общей задачи требуется данное решение?" Опишите проблему целиком, а я уже сам решу, нужно ли вам атрибуты менять и вообще нужно ли само копирование файла.


Вот приходите Вы к дентисту: "вылечите мне зуб". А он такой: "что конкретно Вы имеете ввиду под "вылечите"? У вас пульпит, периодонтит, перикоронит или простой кариес? Вам пломбу поставить, удаление нерва, коронку, удаление зуба или что? Что Вы от меня хотите? Сформулируйте точно!"