Обучаем Liferay Portal 6.0 Ee Sp2 Понимать Файлы Лицензий Для Версии 6.1

Многие разработчики Liferay Portal 6.0 EE были недовольны политикой Liferay Inc., поскольку.

Когда вышла версия 6.1, они потеряли возможность использовать пробные лицензии при работе над проектами, а ключи от новой версии не имеют обратной совместимости.

.

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

Выход есть, пусть он и не самый элегантный, но если у вас не осталось выбора, вы все равно можете решить эту проблему.

Добро пожаловать в кот.



О чем пойдет речь в этой статье

Версия Liferay Portal 6.0 EE использует метод проверки лицензий некоторой сложности (данный раздел в статье не обсуждается), но у него есть очень слабое место (о нем мы и поговорим), которое позволяет, замена тела одного из методов всего в одну строку заставит Liferay принять файлы лицензии от Liferay Portal 6.1 EE. Но это не главное преимущество такого подхода.

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



Немного практики

Рассмотрим класс, выполняющий проверку лицензии, который находится в библиотеке «portal-impl.jar».

Думаю, люди, понимающие, о чем мы говорим, знают, где это искать.

Конечно, в «APP_SERVER/webapps/ROOT/WEB-INF/lib», если используется Tomcat, по аналогии можно найти расположение этого файла при использовании другого сервера приложений.

Итак, перейдем к практической части.

В качестве первого шага, используя инструмент, знакомый разработчикам Java, такой как «JD» или «jad» для «portal-impl.jar», мы получаем код для класса «com.liferay.portal.ee.license.b.d».

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

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

package com.liferay.portal.ee.license.b; import com.liferay.portal.ee.license.a; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.StringUtil; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class d { private static final String[] a = { "MD5", "SHA-1", "SHA-256", "SHA-512" }; private static final String b = "4a4beb2b97c151cff83cbca7096325086817360a7b8c912b66e1d1dea172033a8c5934cbbacbf7b443496cc119a6a482fc6225d28bcbcb2384f52862e6fd35e49a2625f1458d24a1f62e71235dc16b9de5a971e638af32a9784e566f33dd90234d89e1dde83e8a4a100a70d999b2bb7fa77eeb34fd1be9cdf3645f9478b14c2cd6b8f955"; private static final char[] c = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static Log d = LogFactoryUtil.getLog(d.class); private static d e = new d(); public static Map a(a parama) { Date localDate1 = parama.p(); Date localDate2 = parama.c(); return a(parama.i(), parama.p(), parama.a(), parama.f(), parama.g(), parama.m(), parama.n(), parama.l(), parama.k(), parama.j(), parama.b(), localDate2.getTime() - localDate1.getTime(), parama.o()); } public static a b(a parama) { String str = parama.g(); if (!str.equals("trial")) return parama; if (!c(parama)) return parama; parama.e("developer"); Map localMap = a(parama); parama.c(e.a(localMap)); return parama; } public static boolean c(a a1) { String s = a1.i(); if (s.equals("1")) return true; Map map = a(a1); String s1 = e.a(map); if (s1.equals("4a4beb2b97c151cff83cbca7096325086817360a7b8c912b66e1d1dea172033a8c5934cbbacbf7b443496cc119a6a482fc6225d28bcbcb2384f52862e6fd35e49a2625f1458d24a1f62e71235dc16b9de5a971e638af32a9784e566f33dd90234d89e1dde83e8a4a100a70d999b2bb7fa77eeb34fd1be9cdf3645f9478b14c2cd6b8f955")) return false; return s1.equals(a1.d()); } private String a(Map paramMap) { int i = GetterUtil.getInteger((String) paramMap.get("version")); try { if (i == 1) throw new IllegalArgumentException("Invalid version " + i); if (i == 2) return b(paramMap); } catch (Exception localException) { d.error(localException, localException); } return ""; } private String b(Map paramMap) { ArrayList localArrayList = new ArrayList(paramMap.keySet()); Collections.sort(localArrayList); Object localObject = new ArrayList(paramMap.size()); String str1; String str2; for (int i = 0; i < localArrayList.size(); i++) { str1 = (String) paramMap.get(localArrayList.get(i)); str2 = a[(i % a.length)]; String str3 = a(str1, str2); ((List) localObject).

add(str3); } localObject = b((List) localObject); for (int i = 0; i < ((List) localObject).

size(); i++) { str1 = (String) ((List) localObject).

get(i); str2 = a[(i % a.length)]; str1 = a(str1, str2); ((List) localObject).

set(i, str1); } return (String) a((List) localObject); } private String a(String paramString1, String paramString2) { MessageDigest localMessageDigest = null; byte[] arrayOfByte = null; try { localMessageDigest = MessageDigest.getInstance(paramString2); localMessageDigest.update(paramString1.getBytes()); arrayOfByte = localMessageDigest.digest(); } catch (NoSuchAlgorithmException e) { } StringBuilder localStringBuilder = new StringBuilder( arrayOfByte.length << 1); for (int i = 0; i < arrayOfByte.length; i++) { int j = arrayOfByte[i] & 0xFF; localStringBuilder.append(c[(j >> 4)]); localStringBuilder.append(c[(j & 0xF)]); } return localStringBuilder.toString(); } private static Map a(String paramString1, Date paramDate, String paramString2, String paramString3, String paramString4, String paramString5, String paramString6, String paramString7, int paramInt1, int paramInt2, String paramString8, long paramLong, String[] paramArrayOfString) { HashMap localHashMap = new HashMap(); localHashMap.put("version", paramString1); if (!paramString4.equals("trial")) localHashMap.put("startDate", String.valueOf(paramDate.getTime())); localHashMap.put("type", paramString4); localHashMap.put("productVersion", paramString6); localHashMap.put("owner", paramString7); localHashMap.put("description", paramString8); if (paramString4.equals("trial")) localHashMap.put("lifetime", String.valueOf(paramLong)); else localHashMap.put("expirationDate", String.valueOf(paramDate.getTime() + paramLong)); String str1; if (paramString1.equals("1")) { if ((paramString4.equals("cluster")) || (paramString4.equals("developer-cluster"))) { for (int i = 0; i < paramArrayOfString.length; i++) { String str2 = StringUtil.replace(paramArrayOfString[i], "-", ":"); str2 = str2.trim().

toLowerCase(); localHashMap.put("macAddress." + i, str2); } } else if (paramString4.equals("production")) { str1 = paramArrayOfString[0].

trim(); localHashMap.put("serverId", str1); } } else { localHashMap.put("accountEntryName", paramString2); localHashMap.put("licenseEntryName", paramString3); localHashMap.put("productEntryName", paramString5); if ((paramString4.equals("cluster")) || (paramString4.equals("developer-cluster"))) localHashMap.put("maxServers", String.valueOf(paramInt1)); if ((paramString4.equals("developer")) || (paramString4.equals("developer-cluster")) || (paramString4.equals("trial"))) localHashMap.put("maxHttpSessions", String.valueOf(paramInt2)); if (paramString4.equals("production")) { str1 = StringUtil.merge(paramArrayOfString); str1 = str1.toLowerCase(); str1 = StringUtil.replace(str1, "-", ":"); localHashMap.put("serverIds", str1); } } return localHashMap; } private String a(List paramList) { int i = paramList.size(); int j = 0; int k = 2147483647; Iterator localIterator1 = paramList.iterator(); int n; while (localIterator1.hasNext()) { Object localObject = (String) localIterator1.next(); n = ((String) localObject).

length(); j += n; if (n >= k) continue; k = n; } Object localObject = new StringBuilder(j); for (int m = 0; m < k; m++) for (n = 0; n < i; n++) { String str2 = (String) paramList.get(n); ((StringBuilder) localObject).

append(str2.charAt(m)); } Iterator localIterator2 = paramList.iterator(); while (localIterator2.hasNext()) { String str1 = (String) localIterator2.next(); if (str1.length() <= k) continue; ((StringBuilder) localObject).

append(str1.substring(k)); } return (String) ((StringBuilder) localObject).

toString(); } private List b(List paramList) { int i = paramList.size(); int j = i / 4; if (j * 4 < i) j++; ArrayList localArrayList = new ArrayList(4); StringBuilder localStringBuilder = new StringBuilder(); for (int k = 0; k < i; k++) { String str = (String) paramList.get(k); if ((k != 0) && (k % j == 0)) { localArrayList.add(localStringBuilder.toString()); localStringBuilder.setLength(0); } localStringBuilder.append(str); } if (localArrayList.size() < 4) localArrayList.add(localStringBuilder.toString()); return localArrayList; } }

Нас интересует единственный метод, который возвращает результат проверки лицензионного ключа:

public static boolean c(a a1) { .

}

Чтобы каждый файл лицензии прошел проверку, необходимо заменить тело этого метода простой конструкцией, возвращающей значение «true».



public static boolean c(a a1) { return true; }



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

Чтобы начать компиляцию, давайте сначала создадим базовую структуру каталогов:

liferay_license_fix/ src/ classes/ lib/

Сохраним полученный нами исходный код класса, создав в «src/» соответствующие пакету каталоги.

Для компиляции целевого класса нам понадобится дополнительный класс «com.liferay.portal.ee.license.a», который содержится в том же «portal-impl.jar».

При включении этой библиотеки в «путь к классам» целевой класс не будет компилироваться, поскольку он уже содержится в «portal-impl.jar».

Поэтому вам необходимо распаковать файл класса «com.liferay.portal.ee.license.a» в ранее созданный каталог «classes», а также скопировать «portal-service.jar» из «APP_SERVER/lib/ext» в в случае Tomcat или из другого места, в зависимости от вашей конфигурации, в каталог «lib» (вы можете избежать копирования «portal-service.jar», указав его местоположение в опции «classpath» компилятора, но в этой статье будет рассмотрен случае копирования).

У вас должна получиться следующая картина:

liferay_license_fix/ src/ com/ liferay/ portal/ ee/ license/ b/ d.java classes/ com/ liferay/ portal/ ee/ license/ a.class lib/ portal-service.jar

Мы идем в каталог «liferay_license_fix» и компилируем целевой класс с помощью следующей команды:

javac -cp "lib\portal-service.jar;classes" -d classes src\com\liferay\portal\ee\license\b\d.java

Класс, который мы скомпилировали, можно найти здесь:

liferay_license_fix/classes/com/liferay/portal/ee/license/b/d.class



Подготовка патча
Теперь вам нужно заменить исходный класс, содержащийся в «portal-impl.jar», на тот, который получен в результате описанных выше шагов.

Это можно сделать либо вручную, просто заменив файл внутри «portal-impl.jar», либо используя патч и инструмент «patching-tool», входящий в состав Liferay Portal, но нам понадобится инструмент более новой версии, чем LR EE 6.0. , те.

содержится в версии Liferay Poral 6.1 EE, которую можно скачать с официального сайта, и просто заменяет текущую версию «патч-инструмента».

После выполнения вышеописанных действий подготовим патч.

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

Подготовим структуру каталогов патча:

liferay-license-fix-6012/ backup/ WAR_PATH/ WEB-INF/ lib/ portal-impl.jar/ com/ liferay/ portal/ ee/ license/ b/ jdk5/ WAR_PATH/ WEB-INF/ lib/ portal-impl.jar/ com/ liferay/ portal/ ee/ license/ b/ jdk6/ WAR_PATH/ WEB-INF/ lib/ portal-impl.jar/ com/ liferay/ portal/ ee/ license/ b/

Рассмотрим возможный вариант создания структуры каталогов, сначала создайте следующие каталоги «WAR_PATH\WEB-INF/lib/portal-impl.jar/» в «liferay-license-fix-6012/backup» и скопируйте их в «liferay -license-fix-6012/jdk5», а также в «liferay-license-fix-6012/jdk6».

Затем скопируйте скомпилированный выше класс вместе со структурой каталогов пакета «com/liferay/portal/ee/license/b/d.class» в «liferay-license-fix-6012/jdk5» и «liferay-license».

-fix-6012/jdk6».

Теперь вам нужно распаковать исходный класс «com.liferay.portal.ee.license.b.d» из «portal-impl.jar» в «liferay-license-fix-6012/backup/».

Каталог WAR_PATH/WEB-INF/lib/portal-impl .

jar/com/liferay/portal/ee/license/b».

Затем создайте файл «liferay-license-fix-6012/fixpack_documentation.xml» со следующим содержимым:

<Эxml version="1.0"?> <patch> <id>liferay-license-fix-6012</id> <name>liferay-license-fix</name> <patching-tool-version>2</patching-tool-version> <incremental>false</incremental> <version>1</version> <rank>1</rank> <requirements></requirements> <component>security-hotfix</component> <product>6012</product> <fixed-issues></fixed-issues> <module-name></module-name> <module-id></module-id> </patch>

Последним шагом в подготовке патча является создание zip-архива «liferay-license-fix-6012.zip» со всем содержимым каталога «liferay-license-fix-6012», не включая сам каталог.



Управление исправлениями
Чтобы установить патч, вам необходимо скопировать его в «/patching-tool/patches» и инициализировать «patching-tool», если это не было сделано ранее, с помощью следующей команды:

patching-tool auto-discovery

После завершения первоначальной инициализации вы увидите файл «default.properties», в котором при необходимости можно настроить пути расположения экземпляра сервера с Liferay Portal 6.0 EE SP2, к которому будут применены исправления.

Затем с помощью команды:

patching-tool info

Вы можете получить информацию о текущем состоянии (список патчей, а также их статус).

Если вывод содержит следующие строки:

Available patches: [ I] liferay-license-fix-6012 :: Currently not installed; Will be installed.

это означает, что патч можно установить.

Команда для установки патча:

patching-tool install

Если результат команды следующий:

The installation was successful. One patch is installed on the system.

это означает, что патч был успешно установлен.

Если вам необходимо отменить изменения, возникшие в результате установки патча, необходимо выполнить следующую команду:

patching-tool revert

В случае успеха вы увидите следующее сообщение:

Revert has been executed successfully. There is no patch installed on the system.

После этих манипуляций вы можете смело использовать файлы лицензии от Liferay Portal 6.1 EE или создать файл лицензии следующего содержания:

<Эxml version="1.0"?> <license> <account-name>Liferay Developer</account-name> <owner>Developer</owner> <description>Trial license</description> <product-name>Portal Enterprise</product-name> <product-version>6.0 SP 2</product-version> <license-name>Portal Enterprise</license-name> <license-type>enterprise</license-type> <license-version>2</license-version> <start-date>Sunday, January 1, 2012 00:00:00 AM GMT</start-date> <expiration-date>Thursday, January 1, 2099 00:00:00 AM GMT</expiration-date> <max-http-sessions>1000</max-http-sessions> <key></key> </license>

Скачать архив, содержащий все файлы, описанные в статье, а также подготовленный патч и «патч-инструмент» необходимой версии.

УПД.

В комментариях был предложен очень простой способ продления лицензий на LR EE 6.0 SP1/SP2. Спасибо пользователю Саурон .

Теги: #liferay #portal #patch #java #CMS #java

Вместе с данным постом часто просматривают: