Работа с изменениями структуры пакета jar
Я в некотором затруднении, и я ищу некоторую помощь о том, как ее решить. У меня есть некоторый исходный код, который импортирует различные классы из файла jar, созданного из idls. Теперь мне дали новую версию этого idl-файла, который имеет другую структуру пакета, которая нарушает все мои старые операторы импорта. Я не могу изменить операторы импорта, поэтому я пытаюсь увидеть, есть ли способ обойти это. Есть идеи?
В основном меня просят заставить текущий исходный код работать как с новой, так и со старой версиями jar, желательно без изменения кода. Я не думаю, что это возможно, но я надеюсь, что я не прав.
3 ответа
Вот одна вещь, которую вы можете сделать: воссоздать все старые классы и привести их в соответствие с новыми. Например, если у вас было a.Foo
и сейчас b.foo
, вы можете иметь:
package a;
public class Foo {
b.Foo foo;
public void method() {
foo.method();
}
}
package b;
public class Foo {
public void method() {
// Your new code...
}
}
Это немного болезненно, но я боюсь, что это цена, которую нужно заплатить за обратную совместимость.
Другое решение, если структура класса это позволяет, было бы иметь a.Foo
унаследовать b.foo
, так что вам не нужно создавать все методы делегата. Но в зависимости от вашего проекта это может не сработать.
Надеюсь это поможет.
Нет, для этого нет способа. Но если вы хотите массово изменить имя пакета, вы можете использовать команду sed из linux.
Например, если ваш старый пакет com.patito и вы хотите изменить его на org.duck, вы можете сделать что-то вроде:
sed 's/com.patito/org.duck/g' *.java
Все зависит от того, насколько сильно изменение структуры. Если новые классы (с другой функциональностью) заменили старые классы, но сохранили одно и то же имя, вы в значительной степени тост. Если у новых классов просто новые имена / pkgs, вы можете создать оболочку для всех оригинальных импортов.
Например, если исходный класс был:
package my.package;
public class OldClassName{
public void getSomeData(){}
}
Но теперь оно изменилось на:
package my.new.package;
public class NewClassName{
public void getSomeData(){}
}
Вы можете создать оболочку для исходного класса:
package my.package;
import my.new.package;
public class OldClassName extends NewClassName{
}
Предостережения:
- Это королевская боль, если у тебя много занятий
- Вы будете ограничены классами, которые не являются окончательными. Если какой-либо оригинальный импорт является финальным классом, вы просто тост, и лучшее, что вы можете сделать, - это композиция (что означает еще больше работы) и большое делегирование.
Если у вас много классов, вы всегда можете написать небольшую утилиту для генерации упаковщиков для вас...
После того, как вы это сделаете, у вас должна быть возможность выкинуть новую банку с оберткой вместе с новой библиотекой, и все должно работать.