{"id":9679,"date":"2025-10-23T10:55:50","date_gmt":"2025-10-23T08:55:50","guid":{"rendered":"https:\/\/pomoc.comarch.pl\/cee\/?post_type=ht_kb&#038;p=9679"},"modified":"2025-11-06T12:20:34","modified_gmt":"2025-11-06T11:20:34","slug":"komunikacja-app-bez-zaleznosci-od-instalacji","status":"publish","type":"ht_kb","link":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/","title":{"rendered":"Komunikacja app bez zale\u017cno\u015bci od instalacji"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Spis tre\u015bci<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Prze\u0142\u0105cznik Spisu Tre\u015bci\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Wprowadzenie\" >Wprowadzenie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Grupa_docelowa\" >Grupa docelowa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Opis\" >Opis<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Wskazowki_dotyczace_uzytkowania\" >Wskaz\u00f3wki dotycz\u0105ce u\u017cytkowania<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Interfejsy_Klienta_bez_zaleznosci_instalacyjnej\" >Interfejsy Klienta bez zale\u017cno\u015bci instalacyjnej<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Wymagania_dotyczace_interfejsu\" >Wymagania dotycz\u0105ce interfejsu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Parametry_i_wartosci_zwracane\" >Parametry i warto\u015bci zwracane<\/a><ul class='ez-toc-list-level-6' ><li class='ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Widoki_obiektow\" >Widoki obiekt\u00f3w<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Powiazanie_interfejsu\" >Powi\u0105zanie interfejsu<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Wiazanie_interfejsow_w_kolekcjach\" >Wi\u0105zanie interfejs\u00f3w w kolekcjach<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Obiekty_regularne\" >Obiekty regularne<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Przyklad_Parametry_obiektu\" >Przyk\u0142ad: Parametry obiektu<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Hook_Contract_bez_zaleznosci_od_instalacji\" >Hook Contract bez zale\u017cno\u015bci od instalacji<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Przyklad\" >Przyk\u0142ad<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Parametry_i_wartosci_zwracane-2\" >Parametry i warto\u015bci zwracane<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Powiazane_przyjazne_aplikacje\" >Powi\u0105zane (przyjazne) aplikacje<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Programowanie\" >Programowanie<\/a><ul class='ez-toc-list-level-6' ><li class='ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Przyklad-2\" >Przyk\u0142ad<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Wytyczne_programistyczne\" >Wytyczne programistyczne<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/komunikacja-app-bez-zaleznosci-od-instalacji\/#Korzystanie_z_innych_interfejsow\" >Korzystanie z innych interfejs\u00f3w<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h3 id=\"wprowadzenie\" ><span class=\"ez-toc-section\" id=\"Wprowadzenie\"><\/span>Wprowadzenie<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Aplikacje s\u0105 cz\u0119sto rozwijane i utrzymywane niezale\u017cnie od siebie. Systemowo traktowane s\u0105 jako oddzielne komponenty oprogramowania. Aplikacje, kt\u00f3re nie s\u0105 od siebie zale\u017cne, mog\u0105 by\u0107 instalowane i aktualizowane niezale\u017cnie.<\/p>\n<p>Merytorycznie mo\u017ce by\u0107 jednak celowe, aby komunikacja mi\u0119dzy aplikacjami mia\u0142a miejsce: przyk\u0142adowo, poprzez dost\u0119p do danych innej aplikacji lub powiadamianie innych aplikacji o okre\u015blonych zdarzeniach w logice programowej danej aplikacji. Ta komunikacja jest najcz\u0119\u015bciej realizowana przez Hook Contracts, Widoki Obiekt\u00f3w i Klasy Stabilne, co prowadzi do zale\u017cno\u015bci instalacyjnej mi\u0119dzy zaanga\u017cowanymi aplikacjami.<\/p>\n<p>W artykule opisane zosta\u0142y technologie interfejsowe, za pomoc\u0105 kt\u00f3rych aplikacje mog\u0105 si\u0119 ze sob\u0105 komunikowa\u0107 bez powstawania zale\u017cno\u015bci instalacyjnej. Opisane zostan\u0105 r\u00f3wnie\u017c przypadki u\u017cycia dla takich interfejs\u00f3w.<\/p>\n<h3 id=\"grupa-docelowa\" ><span class=\"ez-toc-section\" id=\"Grupa_docelowa\"><\/span>Grupa docelowa<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>Programi\u015bci aplikacji<\/li>\n<\/ul>\n<h3 id=\"opis\" ><span class=\"ez-toc-section\" id=\"Opis\"><\/span>Opis<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<h4 id=\"wskazowki-dotyczace-uzytkowania\" ><span class=\"ez-toc-section\" id=\"Wskazowki_dotyczace_uzytkowania\"><\/span>Wskaz\u00f3wki dotycz\u0105ce u\u017cytkowania<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Dla komunikacji mi\u0119dzy aplikacjami nale\u017cy stosowa\u0107 opisane w tym artykule technologie interfejsowe tylko wtedy, gdy faktycznie nie jest po\u017c\u0105dana zale\u017cno\u015b\u0107 instalacyjna. Je\u017celi w inny spos\u00f3b istnieje ju\u017c zale\u017cno\u015b\u0107 instalacyjna, nale\u017cy zamiast nich u\u017cy\u0107 Klas Stabilnych, Hook Contracts (z zale\u017cno\u015bci\u0105) i Widok\u00f3w Obiekt\u00f3w.<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Z powodu braku zale\u017cno\u015bci instalacyjnej nie jest mo\u017cliwe zapobieganie jednostronnemu aktualizowaniu merytorycznie powi\u0105zanych aplikacji. Aplikacja A, kt\u00f3ra dla funkcjonuj\u0105cej komunikacji potrzebowa\u0142aby r\u00f3wnie\u017c aktualizacji aplikacji B, mo\u017ce wi\u0119c zosta\u0107 zaktualizowana, podczas gdy Aplikacja B z innych powod\u00f3w nie mo\u017ce lub nie ma by\u0107 aktualizowana. Stanowi to problem, je\u015bli komunikacja mi\u0119dzy A i B by\u0142a u\u017cywana przed aktualizacj\u0105. Problem ten musi by\u0107 zweryfikowany dla konkretnego przypadku.<\/div><\/section>\n<p>Interfejsy udost\u0119pnione za pomoc\u0105 opisanych technologii musz\u0105 by\u0107 utrzymywane jako kompatybilne po ich pierwszym udost\u0119pnieniu. Poniewa\u017c nie jest sprawdzana zale\u017cno\u015b\u0107, w systemie mog\u0105 znajdowa\u0107 si\u0119 u\u017cytkownicy, kt\u00f3rzy zostali stworzeni w oparciu o dowoln\u0105, dotychczas udost\u0119pnion\u0105 wersj\u0119 interfejsu. Za pomoc\u0105 opisanych w niniejszym dokumencie technologii interfejsowych mo\u017cliwa jest komunikacja mi\u0119dzy aplikacjami r\u00f3wnie\u017c wtedy, gdy nie s\u0105 one rozwijane w tym samym systemie deweloperskim aplikacji. W takim przypadku komunikacja nie mo\u017ce jednak by\u0107 testowana w systemie deweloperskim aplikacji.<\/p>\n<h4 id=\"interfejsy-klienta-bez-zaleznosci-instalacyjnej\" ><span class=\"ez-toc-section\" id=\"Interfejsy_Klienta_bez_zaleznosci_instalacyjnej\"><\/span>Interfejsy Klienta bez zale\u017cno\u015bci instalacyjnej<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Interfejs Klienta (Client Interface) jest interfejsem aplikacji dostawcy (Provider-App), w kt\u00f3rym aplikacja u\u017cytkownika (User-App) mo\u017ce wywo\u0142ywa\u0107 metody. Zale\u017cno\u015b\u0107 instalacyjna jest unikana poprzez to, \u017ce wywo\u0142ania metod odbywaj\u0105 si\u0119 za po\u015brednictwem Proxy Java.<\/p>\n<p>Poni\u017csza grafika pokazuje sk\u0142adowe Interfejsu Klienta bez zale\u017cno\u015bci instalacyjnej. Aplikacja dostawcy (Provider-App) udost\u0119pnia interfejs (Interface), w kt\u00f3rym definiowane s\u0105 dost\u0119pne metody, i zawiera implementacj\u0119 tego interfejsu (Implementation). Aplikacja u\u017cytkownika (User-App) zawiera kopi\u0119 tego interfejsu w swojej w\u0142asnej przestrzeni nazw. W kodzie aplikacji u\u017cytkownika (Klasa <em>Caller<\/em> na grafice) metody s\u0105 wywo\u0142ywane w obiekcie <em>Implementation<\/em> za po\u015brednictwem Proxy Java.<\/p>\n<figure id=\"attachment_39810\" aria-describedby=\"caption-attachment-39810\" style=\"width: 1517px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-39810\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji.png\" alt=\"\" width=\"1517\" height=\"740\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji.png 1517w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji-300x146.png 300w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji-1024x500.png 1024w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji-768x375.png 768w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/Interfejs-klienta-bez-zaleznosci-od-instalacji-50x24.png 50w\" sizes=\"auto, (max-width: 1517px) 100vw, 1517px\" \/><\/a><figcaption id=\"caption-attachment-39810\" class=\"wp-caption-text\">Interfejs klienta bez zale\u017cno\u015bci od instalacji<\/figcaption><\/figure>\n<p>Po\u0142\u0105czenie zrealizowane przez Java-Proxy skopiowanego interfejsu w aplikacji u\u017cytkownika oraz implementacji w aplikacji dostawcy jest w dalszej cz\u0119\u015bci artyku\u0142u nazywane <i>wi\u0105zaniem interfejsu<\/i>. Interfejs w aplikacji dostawcy s\u0142u\u017cy programi\u015bcie aplikacji u\u017cytkownika jako artyku\u0142 oraz jako szablon do kopiowania. Adnotacja @InvocationTarget na interfejsie okre\u015bla klas\u0119 implementacji, dzi\u0119ki czemu znany jest cel wywo\u0142a\u0144 metod. Specyfikacja jest tworzona jako ci\u0105g znak\u00f3w, dzi\u0119ki czemu adnotacja mo\u017ce zosta\u0107 przyj\u0119ta bez zmian w skopiowanym interfejsie. Tylko ta kopia jest wymagana do wywo\u0142ania metody.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Provider-App B, Interface:\n\npackage com.provider.ext.app.b.template;\n\nimport com.cisag.pgm.appserver.InvocationTarget;\n\n \n\n@InvocationTarget(\u201ccom.provider.ext.app.b.log.Implementation\u201d)\n\ninterface Interface {\n\nString method(\u2026);\n\n}\n\nProvider-App B, Implementacja:\n\npackage com.provider.ext.app.b.log;\n\n \n\nclass Implementation implements com.provider.ext.app.b.template.Interface {\n\nString method(\u2026) { \u2026 }\n\n}\n\nUser-App A, Interface:\n\nInterfejs jest kopiowany do aplikacji u\u017cytkownika, przy czym nale\u017cy jedynie wymieni\u0107 pakiet:\npackage com.user.ext.app.a.log;\n\nimport com.cisag.pgm.appserver.InvocationTarget;\n\n \n\n@InvocationTarget(\u201ccom.provider.ext.app.b.log.Implementation\u201d)\n\ninterface Interface {\n\nString method(\u2026);\n\n}<\/pre>\n<p><\/div><\/section><br \/>\nIstnieje po\u0142\u0105czenie mi\u0119dzy interfejsem w aplikacji u\u017cytkownika a implementacj\u0105 w aplikacji dostawcy. Aby m\u00f3c wywo\u0142ywa\u0107 metody, aplikacja u\u017cytkownika tworzy obiekt implementacji i obiekt Java-Proxy, kt\u00f3ry reprezentuje interfejs <em>Interface<\/em> za pomoc\u0105 metody pomocniczej w PGM. Aplikacja u\u017cytkownika mo\u017ce nast\u0119pnie wywo\u0142ywa\u0107 metody na tym obiekcie Java-Proxy, przy czym wywo\u0142ania s\u0105 przekazywane do obiektu implementacji przez Java-Proxy.<br \/>\nJe\u015bli aplikacja dostawcy nie jest zainstalowana, zamiast obiektu proxy zwracana jest warto\u015b\u0107 <em>null<\/em>.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">\n<p>Przyk\u0142ad wywo\u0142ania metody:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.user.ext.app.a.log.Interface;\n:\nCisProxyManager xm= CisEnviron-ment.getInstance().getProxyManager();\nInterfejs intf = xm.createImplementation(Interface.class);\nIf (intf != null) {\nString s = intf.method();\n\/\/...\n}<\/pre>\n<p><\/div><\/section><br \/>\nGdy wywo\u0142ywana jest metoda, kolejka komunikat\u00f3w nie jest izolowana. Odpowiada to zachowaniu podczas wywo\u0142ywania stabilnych metod, ale r\u00f3\u017cni si\u0119 od hook contract.<br \/>\nInterfejs powinien by\u0107 udokumentowany bezpo\u015brednio w aplikacji dostawcy za pomoc\u0105 JavaDoc. Oznacza to, \u017ce dokumentacja jest kopiowana podczas kopiowania interfejsu i jest dost\u0119pna w kodzie aplikacji u\u017cytkownika.<\/p>\n<h5 id=\"wymagania-dotyczace-interfejsu\" ><span class=\"ez-toc-section\" id=\"Wymagania_dotyczace_interfejsu\"><\/span>Wymagania dotycz\u0105ce interfejsu<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>W aplikacji dostawcy interfejs powinien by\u0107 zapisany w podprzestrzeni nazw <em>template<\/em> obok przestrzeni nazw <em>log<\/em>. Adnotacja @InvocationTarget pozwala na u\u017cycie interfejsu jako interfejsu klienta bez zale\u017cno\u015bci od instalacji. W aplikacji u\u017cytkownika interfejs mo\u017cna wprowadzi\u0107 w dowolnej przestrzeni nazw, nawet jako interfejs wewn\u0119trzny.<br \/>\nKlasa implementacji nie mo\u017ce by\u0107 klas\u0105 wewn\u0119trzn\u0105. Obiekty tej klasy s\u0105 tworzone przez CisProxyManager za pomoc\u0105 CisFactory.createInstance().<br \/>\nTylko metody dost\u0119pne w interfejsie Java mog\u0105 by\u0107 wywo\u0142ywane przez proxy. U\u017cycie jakichkolwiek odziedziczonych metod prowadzi do wyj\u0105tku RuntimeException. Wyj\u0105tkiem s\u0105 odziedziczone metody hashCode() i toString(). Mog\u0105 one by\u0107 wywo\u0142ywane, je\u015bli nie zosta\u0142y nadpisane explicit w interfejsie Java.<\/p>\n<h5 id=\"parametry-i-wartosci-zwracane\" ><span class=\"ez-toc-section\" id=\"Parametry_i_wartosci_zwracane\"><\/span><a id=\"piwz\"><\/a>Parametry i warto\u015bci zwracane<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Metody w interfejsie mog\u0105 by\u0107 wywo\u0142ywane z parametrami i warto\u015bciami zwracanymi. Podczas gdy typy prymitywne (short, int, char itp.) mog\u0105 by\u0107 u\u017cywane bez ogranicze\u0144, ograniczenia opisane poni\u017cej maj\u0105 zastosowanie do niekt\u00f3rych typ\u00f3w obiekt\u00f3w.<\/p>\n<h6 id=\"widoki-obiektow\" ><span class=\"ez-toc-section\" id=\"Widoki_obiektow\"><\/span>Widoki obiekt\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Widoki obiekt\u00f3w s\u0105 interfejsami, kt\u00f3rych nie mo\u017cna kopiowa\u0107 1:1. Nie mo\u017cna ich zatem u\u017cywa\u0107 jako parametr\u00f3w dla wi\u0105zania interfejsu.<\/p>\n<h6 id=\"powiazanie-interfejsu\" ><span class=\"ez-toc-section\" id=\"Powiazanie_interfejsu\"><\/span><a id=\"pi\"><\/a>Powi\u0105zanie interfejsu<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Interfejsy, dla kt\u00f3rych dost\u0119pne jest powi\u0105zanie interfejsu, mog\u0105 by\u0107 u\u017cywane nie tylko jako interfejsy klienta, ale tak\u017ce jako parametry metod. Parametry metody musz\u0105 zosta\u0107 utworzone w aplikacji u\u017cytkownika za pomoc\u0105 createImplementation(.). W czasie wykonywania przekazane obiekty proxy s\u0105 zast\u0119powane odpowiednimi instancjami implementacji. Aplikacja dostawcy nie otrzymuje proxy, ale implementacj\u0119 ze swojego modu\u0142u, kt\u00f3ra bezpo\u015brednio implementuje interfejs z aplikacji dostawcy.<br \/>\nPodobnie, interfejsy z wi\u0105zaniem interfejsu mog\u0105 by\u0107 dostarczane jako zwrot. W tym przypadku metoda aplikacji dostawcy zwraca instancj\u0119 implementacji. Jest ona dostarczana z instancj\u0105 proxy dla aplikacji u\u017cytkownika, kt\u00f3ra realizuje interfejs aplikacji u\u017cytkownika.<br \/>\nInterfejsy, kt\u00f3rych powi\u0105zanie interfejsu ma zosta\u0107 rozwi\u0105zane w czasie wykonywania, musz\u0105 zosta\u0107 zarejestrowane jawnie przez aplikacj\u0119 u\u017cytkownika podczas tworzenia obiektu implementacji za pomoc\u0105 createImplementation(.):<\/p>\n<p>CisProxyManager.createImplementation( Class&lt;?&gt; intf, Class&lt;?&gt;&#8230; ad-ditionalInterfaces).<\/p>\n<p>Niezarejestrowane interfejsy z wi\u0105zaniem interfejsu s\u0105 traktowane jak zwyk\u0142e obiekty i przekazywane bezpo\u015brednio, szczeg\u00f3\u0142y dost\u0119pne w rozdziale <em><a href=\"#or\">Obiekty regularne<\/a><\/em>.<br \/>\nInterfejsy mo\u017cna r\u00f3wnie\u017c zarejestrowa\u0107 p\u00f3\u017aniej dla obiektu proxy, wywo\u0142uj\u0105c nast\u0119puj\u0105c\u0105 metod\u0119:<\/p>\n<p>CisProxyManager.registerAdditionalInterfaces(Proxy, Class&lt;?&gt;&#8230; ad-ditionalInterfaces).<\/p>\n<p>Zwykle jest to konieczne tylko wtedy, gdy obiekt implementacji zosta\u0142 automatycznie dostarczony z instancj\u0105 proxy jako warto\u015bci\u0105 zwracan\u0105 wywo\u0142ania metody, a nie zosta\u0142 utworzony przez createImplementation(.).<\/p>\n<h6 id=\"wiazanie-interfejsow-w-kolekcjach\" ><span class=\"ez-toc-section\" id=\"Wiazanie_interfejsow_w_kolekcjach\"><\/span>Wi\u0105zanie interfejs\u00f3w w kolekcjach<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Je\u015bli kolekcje s\u0105 parametrami lub warto\u015bciami zwracanymi wywo\u0142ania metody, interfejsy z wi\u0105zaniem interfejsu zawarte w kolekcjach s\u0105 rozwi\u0105zywane w czasie wykonywania. Warunkiem wst\u0119pnym jest to, \u017ce parametr lub warto\u015b\u0107 zwracana w metodzie jest zadeklarowana jako jeden z nast\u0119puj\u0105cych interfejs\u00f3w:<\/p>\n<ul>\n<li>java.lang.Iterable<\/li>\n<li>java.util.Collection<\/li>\n<li>java.util.List<\/li>\n<li>java.util.Set<\/li>\n<li>java.util.Map<\/li>\n<li>com.cisag.pgm.util.CisMap<\/li>\n<\/ul>\n<p>Je\u015bli zadeklarowano inny interfejs kolekcji lub inn\u0105 klas\u0119 kolekcji, nie ma powi\u0105zania interfejsu.<br \/>\nPodczas wywo\u0142ywania metod kolekcje s\u0105 opakowywane przez obiekty proxy, wi\u0119c nie jest mo\u017cliwe rzutowanie kolekcji na okre\u015blon\u0105 klas\u0119 kolekcji.<br \/>\nInterfejsy zawarte jako elementy, kt\u00f3rych wi\u0105zanie interfejsu ma zosta\u0107 rozwi\u0105zane w czasie wykonywania, musz\u0105 by\u0107 jawnie zarejestrowane przez aplikacj\u0119 u\u017cytkownika, szczeg\u00f3\u0142y mo\u017cna znale\u017a\u0107 w rozdziale <em><a href=\"#pi\">Powi\u0105zanie interfejsu<\/a><\/em>.<br \/>\nKolekcje mog\u0105 by\u0107 zagnie\u017cd\u017cane zgodnie z wymaganiami.<\/p>\n<h6 id=\"obiekty-regularne\" ><span class=\"ez-toc-section\" id=\"Obiekty_regularne\"><\/span><a href=\"http:\/\/or\" data-wplink-url-error=\"true\">Obiekty regularne<\/a><span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Wszystkie obiekty, dla kt\u00f3rych nie ma zastosowania \u017cadna z procedur opisanych w poprzednich rozdzia\u0142ach, s\u0105 przenoszone bezpo\u015brednio. Dotyczy to w szczeg\u00f3lno\u015bci tablic.<br \/>\nW razie potrzeby bardziej z\u0142o\u017cone struktury danych mog\u0105 by\u0107 mapowane w aplikacji dostawcy jako oddzielny interfejs z powi\u0105zaniem interfejsu, szczeg\u00f3\u0142y mo\u017cna znale\u017a\u0107 w rozdziale <em><a href=\"#pi\">Powi\u0105zanie interfejsu<\/a><\/em>.<\/p>\n<h6 id=\"przyklad-parametry-obiektu\" ><span class=\"ez-toc-section\" id=\"Przyklad_Parametry_obiektu\"><\/span>Przyk\u0142ad: Parametry obiektu<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Obiekt kontenera <em>UserData<\/em> ma by\u0107 u\u017cywany jako parametr i warto\u015b\u0107 zwracana w metodach interfejsu. Zar\u00f3wno interfejs, jak i obiekt kontenera s\u0105 dostarczane jako interfejs z powi\u0105zaniem interfejsu.<br \/>\nObiekt kontenera<br \/>\nProvider app B, interfejs:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">package com.provider.ext.app.b.template;\n:\n@InvocationTarget(\"com.provider.ext.app.b.log.UserDataImplementation\")\ninterface UserDataInterface {\nvoid setData(...);\nObject getData();\n}<\/pre>\n<p>Provider app B, implementacja:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">package com.provider.ext.app.b.log;\nimport com.provider.ext.app.b.template.UserDataInterface;\n\nclass UserDataImplementation implements UserDataInterface {\nvoid setData(...) { ... }\nObject getData() { ... }\n}<\/pre>\n<p>User app A, Interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">package com.user.ext.app.a.obj;\n:\n@InvocationTarget(\"com.provider.ext.app.b.log.UserDataImplementation\")\ninterface UserDataInterface {\nvoid setData(...);\nObject getData();\n}<\/pre>\n<p>Interfejs <em>Interface<\/em> wraz z jego implementacj\u0105<br \/>\nProvider app B, Interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.provider.ext.app.b.template.UserDataInterface;\n:\ninterface {\nvoid initUserData (UserDataInterface user);\nUserDataInterface getUserData();\nBoolean printUserDatas(java.util.list&lt;UserDataInterface&gt; datas);\n}<\/pre>\n<p>Provider app B, implementacja:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.provider.ext.app.b.template.UserDataInterface;\n:\nclass Implementation implements Interface {\nvoid initUserData (UserDataInterface user) { ... }\nUserDataInterface getUserData() { ... };\nboolean printUserDatas(java.util.list&lt;UserDataInterface&gt; datas)\n{ ... }\n}<\/pre>\n<p>Aplikacja u\u017cytkownika A, interfejs:<br \/>\nPodczas przesy\u0142ania kontenera danych do aplikacji u\u017cytkownika A nale\u017cy wymieni\u0107 tylko pakiet i dostosowa\u0107 wszelkie importy.<\/p>\n<p>import com.user.ext.app.a.log.UserDataInterface;<br \/>\n:<br \/>\ninterface Interface {<br \/>\nString method(&#8230;);<\/p>\n<p>void initUserData (UserDataInterface user);<br \/>\nUserDataInterface getUserData();<br \/>\nboolean printUserDatas(java.util.list&lt;UserDataInterface&gt; datas);<br \/>\n}<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.user.ext.app.a.log.UserDataInterface;\n:\ninterface Interface {\nString method(...);\n\nvoid initUserData (UserDataInterface user);\nUserDataInterface getUserData();\nboolean printUserDatas(java.util.list&lt;UserDataInterface&gt; datas);\n}<\/pre>\n<p>Wywo\u0142ania metod<br \/>\nR\u00f3\u017cne wywo\u0142ania metod przez aplikacj\u0119 u\u017cytkownika A z <em>UserData<\/em> jako parametrem lub warto\u015bci\u0105 zwracan\u0105:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.user.ext.app.a.log.Interface;\nimport com.user.ext.app.a.log.UserDataInterface;\n:\nCisProxyManager xm= CisEnvironment.getInstance().getProxyManager();\n\nUserDataInterface userData = xm.createImplementation(UserDataInterface.class);\n\nInterfejs intf = xm.createImplementation(Interface.class, UserDataInterface.class);\nIf (intf != null) {\n\nintf.initUserData(userData);\nUserDataInterface userData2 = intf.getUserData();\n\njava.util.ArrayList datas = new ArrayList();\ndatas.add(userData);\ndatas.add(userData2);\nBoolean ok = printUserDatas(datas);\n}<\/pre>\n<h4 id=\"hook-contract-bez-zaleznosci-od-instalacji\" ><span class=\"ez-toc-section\" id=\"Hook_Contract_bez_zaleznosci_od_instalacji\"><\/span>Hook Contract bez zale\u017cno\u015bci od instalacji<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Hook Contract to technologia interfejsu, w kt\u00f3rej aplikacja dostawcy zapewnia interfejs (hook), a aplikacje u\u017cytkownika mog\u0105 si\u0119 zarejestrowa\u0107, aby by\u0107 wywo\u0142ywane w ramach tego interfejsu.<br \/>\nPoni\u017cszy schemat przedstawia sk\u0142adniki hook contract , gdy s\u0105 u\u017cywane bez zale\u017cno\u015bci od instalacji. Hook Contract z hookiem jest dostarczany w aplikacji dostawcy i s\u0105 zaimplementowane w aplikacji u\u017cytkownika. W przypadku hook contract , implementacja hooka jest wywo\u0142ywana przez aplikacj\u0119 dostawcy.<\/p>\n<figure id=\"attachment_39813\" aria-describedby=\"caption-attachment-39813\" style=\"width: 1536px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-39813\" src=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2.png\" alt=\"\" width=\"1536\" height=\"1024\" srcset=\"https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2.png 1536w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2-300x200.png 300w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2-1024x683.png 1024w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2-768x512.png 768w, https:\/\/pomoc.comarch.pl\/cee\/wp-content\/uploads\/2025\/10\/zrzut2-50x33.png 50w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><\/a><figcaption id=\"caption-attachment-39813\" class=\"wp-caption-text\">Hook Contract bez zale\u017cno\u015bci od instalacji<\/figcaption><\/figure>\n<p>W aplikacji dostawcy nie jest wymagane specjalne oznaczenie ani hooka, ani hook contract do u\u017cytku bez zale\u017cno\u015bci od instalacji. Hooki musz\u0105 spe\u0142nia\u0107 warunki okre\u015blone w rozdziale <em><a href=\"#piwz\">Parametry i warto\u015bci zwracane<\/a><\/em>, aby mog\u0142y by\u0107 u\u017cywane bez zale\u017cno\u015bci od instalacji.<br \/>\nW aplikacji u\u017cytkownika implementacja hook contract musi by\u0107 oznaczona do u\u017cytku bez zale\u017cno\u015bci od instalacji. W tym celu atrybut <em>dependency<\/em> elementu <em>contract<\/em> w definicji XML jest ustawiony na <em>false<\/em> (warto\u015b\u0107 domy\u015blna to <em>true<\/em>). Dzi\u0119ki takiemu oznaczeniu implementacja hook contract mo\u017ce by\u0107 r\u00f3wnie\u017c aktywowana jako obiekt deweloperski bez definicji hook contract lub interfejsu klasy Java, a zatem nie jest zale\u017cna od instalacji definicji hook contract.<br \/>\nW przypadku implementacji hook istnieje wyb\u00f3r mi\u0119dzy:<\/p>\n<ul>\n<li>skopiowaniem interfejsu hooka do aplikacji u\u017cytkownika i wyprowadzeniem z niego implementacji<\/li>\n<li>lub skopiowa\u0107 metody hooka do implementacji z niezmienion\u0105 sygnatur\u0105 i, z przyczyn technicznych, bezpo\u015brednio zaimplementowa\u0107 pusty interfejs com.cisag.pgm.base.Hook.<\/li>\n<\/ul>\n<p>W obu przypadkach tworzone jest powi\u0105zanie interfejsu. Zaleca si\u0119 skopiowanie interfejsu hooka do aplikacji u\u017cytkownika w celu unikni\u0119cia b\u0142\u0119d\u00f3w programistycznych.<br \/>\nJe\u015bli aplikacja dostawcy nie jest dost\u0119pna w czasie wykonywania i dlatego brakuje definicji hook contract, hook lub implementacja hooka nie zostanie wywo\u0142ana.<br \/>\nI odwrotnie, je\u015bli aplikacja u\u017cytkownika nie jest dost\u0119pna w czasie wykonywania, wywo\u0142anie hooka przez aplikacj\u0119 dostawcy &#8211; podobnie jak w przypadku hook contract z zale\u017cno\u015bci\u0105 instalacyjn\u0105 &#8211; nie ma \u017cadnego efektu.<br \/>\nJe\u015bli definicja hook contract jest dost\u0119pna w czasie wykonywania, ale nie zawiera interfejsu haooka, jego wywo\u0142anie r\u00f3wnie\u017c nie ma \u017cadnego efektu. W takim przypadku aplikacja dostawcy jest prawdopodobnie zainstalowana w nieaktualnej wersji. To, czy jest to problem, musi by\u0107 oceniane indywidualnie dla ka\u017cdego przypadku.<\/p>\n<p>We wszystkich innych aspektach hook contract zachowuj\u0105 si\u0119 tak, jak opisano w dokumentacji<a href=\"https:\/\/pomoc.comarch.pl\/cee\/index.php\/documentation\/hook-contracts\/\"><em> Hook Contract<\/em><\/a>.<\/p>\n<h5 id=\"przyklad\" ><span class=\"ez-toc-section\" id=\"Przyklad\"><\/span>Przyk\u0142ad<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Implementacja hook contract<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">:\n&lt;contract dependency=\"false\"&gt;com...b...HookContractDef&lt;\/contract&gt;\n&lt;hook&gt;\n&lt;interface&gt;com.provider.ext.app.b.hook.HookInterface&lt;\/interface&gt;\n&lt;implementation&gt;com.user.ext.app.a.log.HookImpl&lt;\/implementation&gt;\n&lt;\/hook&gt;\n:<\/pre>\n<p>Aplikacja u\u017cytkownika A, skopiowany interfejs hook(opcjonalnie)<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">package com.user.ext.app.a.log;\n\/* Skopiowany interfejs com.provider.ext.app.b.hook.HookInterface *\/\npublic interface HookInterface extends com.cisag.pgm.base.Hook {\n:\n}<\/pre>\n<p>Aplikacja u\u017cytkownika A, implementacja hook<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">class HookImpl implements com.user.ext.app.a.log.HookInterface {\n:\n}\nlub\nclass HookImpl implements com.cisag.pgm.base.Hook {\n:\n}<\/pre>\n<h5 id=\"parametry-i-wartosci-zwracane\" ><span class=\"ez-toc-section\" id=\"Parametry_i_wartosci_zwracane-2\"><\/span>Parametry i warto\u015bci zwracane<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Dla parametr\u00f3w i warto\u015bci zwracanych metod hook obowi\u0105zuj\u0105 nast\u0119puj\u0105ce ograniczenia:<\/p>\n<ul>\n<li><span style=\"font-size: revert; color: initial;\">Interfejs z wi\u0105zaniem interfejsu i implementacj\u0105 w aplikacji proxy mo\u017ce by\u0107 u\u017cywany w metodach hak\u00f3w jako parametry i warto\u015bci zwracane; automatyczne dopasowywanie typ\u00f3w odbywa si\u0119 za po\u015brednictwem serwer\u00f3w proxy. Nie dotyczy to jednak element\u00f3w w kolekcjach: mog\u0105 one by\u0107 przekazywane, ale nadal korzystaj\u0105 z interfejsu aplikacji dostawcy.<\/span><\/li>\n<li>ponadto te same ograniczenia maj\u0105 zastosowanie do parametr\u00f3w i warto\u015bci zwracanych w umowach hook, jak w interfejsach klienta.<\/li>\n<\/ul>\n<p>W przypadku korzystania z hook contract bez zale\u017cno\u015bci od instalacji, interfejsy, kt\u00f3rych powi\u0105zanie interfejsu ma zosta\u0107 rozwi\u0105zane w czasie wykonywania, musz\u0105 by\u0107 jawnie zarejestrowane przez aplikacj\u0119 dostawcy. W przypadku wywo\u0142ania hooka, aplikacja dostawcy najpierw generuje implementacje hooka:<\/p>\n<p>Collection&lt;Hook&gt; CisHookManager.getHookImplementations(Class con-tract, Class interf)<\/p>\n<p>lub<\/p>\n<p>Hook CisHookManager.getHookContainer(Class contract, Class interf).<\/p>\n<p>Nast\u0119puj\u0105ce metody s\u0105 nast\u0119pnie wywo\u0142ywane w celu zarejestrowania dodatkowych interfejs\u00f3w dla wi\u0105zania interfejs\u00f3w parametr\u00f3w lub warto\u015bci zwracanych:<\/p>\n<p>CisProxyManager.registerAdditionalInterfaces(Collection&lt;Hook&gt;, Class&lt;?&gt;&#8230; additionalInterfaces)<\/p>\n<p>lub<\/p>\n<p>CisProxyManager.registerAdditionalInterfaces(Hook, Class&lt;?&gt;&#8230; additionalInterfaces)<\/p>\n<p>Obiekty z obs\u0142ug\u0105 wi\u0105zania interfejs\u00f3w, kt\u00f3re maj\u0105 by\u0107 przekazywane jako parametry, s\u0105 tworzone bezpo\u015brednio przez aplikacj\u0119 dostawcy dla wywo\u0142ania hooka, jak pokazano w poni\u017cszym przyk\u0142adzie. W przeciwie\u0144stwie do tego, aby zwr\u00f3ci\u0107 obiekt z wi\u0105zaniem interfejsu, obiekt ten jest najpierw tworzony w implementacji hooka za pomoc\u0105 CisProxyMana-ger.createImplementation(.).<\/p>\n<p>[exampleParametry dla wywo\u0142a\u0144 hook<br \/>\nPrzyk\u0142ad pokazuje wywo\u0142anie hooka w aplikacji dostawcy z obs\u0142ug\u0105 wi\u0105zania interfejsu. Aplikacja dostawcy przekazuje implementacj\u0119 interfejsu w wywo\u0142aniu haka.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import com.provider.ext.app.b.template.Interface;\nimport com.provider.ext.app.b.template.UserDataInterface;\n:\nCisProxyManager xm= CisEnvironment.getInstance().getProxyManager();\n\nUserDataInterface userData = new UserData();\n\nInterfejs hook =\nhm.getHookContainer(com.provider.ext.app.b.ContextClass.class,\nInterface.class);\nxm.registerAdditionalInterfaces(hook, UserDataInterface.class);\nhook.initUserData(userData);<\/pre>\n<p>Implementacja hooka u\u017cywa kopii interfejsu w swojej sygnaturze metody i mo\u017ce go u\u017cy\u0107 do uzyskania dost\u0119pu do przekazanego obiektu.<\/p>\n<p>][\/example]<\/p>\n<h4 id=\"powiazane-przyjazne-aplikacje\" ><span class=\"ez-toc-section\" id=\"Powiazane_przyjazne_aplikacje\"><\/span>Powi\u0105zane (przyjazne) aplikacje<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metody opisane powy\u017cej wykorzystuj\u0105 sprz\u0119\u017cenie interfejsu mi\u0119dzy zaanga\u017cowanymi aplikacjami, tj. aplikacja A musi zapewni\u0107 interfejs, za po\u015brednictwem kt\u00f3rego aplikacja B mo\u017ce uzyska\u0107 do niej dost\u0119p. Interfejsy te s\u0105 przydatne w przypadku wywo\u0142a\u0144 funkcjonalnych z prost\u0105 struktur\u0105 parametr\u00f3w. Nie nadaj\u0105 si\u0119 one na przyk\u0142ad do wymiany danych masowych w zwi\u0105zku z dost\u0119pem do bazy danych. Jak opisano powy\u017cej, parametry metody musz\u0105 by\u0107 indywidualnie przypisane do proxy za pomoc\u0105 <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">createImplementation(.)<\/code>. Je\u015bli wymieniane maj\u0105 by\u0107 kompletne obiekty biznesowe, ka\u017cda pojedyncza instancja musi by\u0107 przygotowana osobno. Przede wszystkim metody Persistence service nie mog\u0105 by\u0107 u\u017cywane bezpo\u015brednio do odczytu obiekt\u00f3w biznesowych w zwyk\u0142y spos\u00f3b.<br \/>\nTak zwane &#8222;przyjazne aplikacje&#8221; umo\u017cliwiaj\u0105 aplikacji A dost\u0119p do niekt\u00f3rych obiekt\u00f3w deweloperskich aplikacji B, tak jakby sama je utworzy\u0142a. Jest to szczeg\u00f3lnie przydatne w przypadku obiekt\u00f3w biznesowych i klas Java.<br \/>\nOpr\u00f3cz &#8222;przyjaznych aplikacji&#8221;, poni\u017cej opisano inne mo\u017cliwe typy zale\u017cno\u015bci mi\u0119dzy dwiema aplikacjami. Mo\u017cna je zdefiniowa\u0107 w aplikacji<em> Panel System<\/em> w polu <em>Typ<\/em> wskaza\u0107 opcj\u0119 G<em>rupa system\u00f3w<\/em> na zak\u0142adce <em>Przyporz\u0105dkowania modu\u0142u<\/em>.<\/p>\n<p><strong>Brak zale\u017cno\u015bci<\/strong><\/p>\n<p>Domy\u015blnie aplikacja A nie mo\u017ce odwo\u0142ywa\u0107 si\u0119 do \u017cadnych obiekt\u00f3w deweloperskich z aplikacji B. Pr\u00f3by zameldowania lub aktywowania odpowiednich element\u00f3w z aplikacji A powoduj\u0105 wy\u015bwietlenie komunikatu o b\u0142\u0119dzie. Oznacza to, \u017ce nie mog\u0105 powsta\u0107 \u017cadne zale\u017cno\u015bci instalacyjne. Je\u015bli zale\u017cno\u015b\u0107 mi\u0119dzy dwiema aplikacjami nie jest wyra\u017anie zdefiniowana w grupie systemowej, ten status ma zastosowanie.<\/p>\n<p><strong>Wymagany modu\u0142<\/strong><\/p>\n<p>Aplikacja B mo\u017ce zosta\u0107 wprowadzona jako <em>Wymagany modu\u0142<\/em> dla aplikacji A. Ma to nast\u0119puj\u0105ce skutki:<\/p>\n<ul>\n<li>Obiekty deweloperskie z aplikacji B mog\u0105 by\u0107 wywo\u0142ywane w aplikacji A. Chocia\u017c jest to dozwolone, nie jest zalecane, dlatego prowadzi do ostrze\u017cenia.<\/li>\n<li>Klasy Java z aplikacji A mog\u0105 wywo\u0142ywa\u0107 metody klas z aplikacji B. Je\u015bli jednak metody te nie zostan\u0105 zidentyfikowane jako stabilne, pojawi si\u0119 ostrze\u017cenie.<\/li>\n<li>Wp\u0142yw na instalacj\u0119: wszystkie aplikacje zadeklarowane jako &#8222;wymagane&#8221; przez aplikacj\u0119 A musz\u0105 by\u0107 ju\u017c zainstalowane w systemie docelowym, w przeciwnym razie instalacja zostanie anulowana.<\/li>\n<\/ul>\n<p><strong>Przyjazny (powi\u0105zany) modu\u0142<\/strong><\/p>\n<p>Aplikacja B mo\u017ce zosta\u0107 zadeklarowana jako &#8222;przyjazny modu\u0142&#8221; aplikacji A. Ma to nast\u0119puj\u0105ce skutki:<\/p>\n<ul>\n<li>Obiekty deweloperskie z aplikacji B mog\u0105 by\u0107 wywo\u0142ywane w aplikacji A. Nie jest wy\u015bwietlane \u017cadne ostrze\u017cenie.<\/li>\n<li>Klasy Java z aplikacji A mog\u0105 wywo\u0142ywa\u0107 metody klas z aplikacji B. Nie ma ostrze\u017cenia dla niestabilnych metod.<\/li>\n<li>Wp\u0142yw na instalacj\u0119: nie jest konieczne, aby aplikacja B by\u0142a ju\u017c zainstalowana podczas instalacji aplikacji A.<\/li>\n<\/ul>\n<p><section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Je\u015bli aplikacja B jest zaprzyja\u017aniona aplikacji A, nie oznacza to automatycznie, \u017ce aplikacja A jest r\u00f3wnie\u017c zaprzyja\u017aniona aplikacji B. Musi to zosta\u0107 wyra\u017anie zadeklarowane.<\/div><\/section><br \/>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Deklaracja jako &#8222;Przyjazny modu\u0142&#8221; zale\u017cy od grupy systemowej, poniewa\u017c dost\u0119p do przyjaznej aplikacji jest zaimplementowany tylko od okre\u015blonego wydania, na przyk\u0142ad.<\/div><\/section><br \/>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Niezale\u017cnie od zdefiniowanej zale\u017cno\u015bci, odwo\u0142ywanie si\u0119 do obiektu programistycznego z aplikacji B przez aplikacj\u0119 A zawsze tworzy zale\u017cno\u015b\u0107, kt\u00f3r\u0105 nale\u017cy wzi\u0105\u0107 pod uwag\u0119, zw\u0142aszcza podczas instalacji.<\/div><\/section><\/p>\n<h5 id=\"programowanie\" ><span class=\"ez-toc-section\" id=\"Programowanie\"><\/span>Programowanie<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Programowanie odbywa si\u0119 w \u015brodowisku, w kt\u00f3rym zainstalowane s\u0105 wszystkie uczestnicz\u0105ce aplikacje. W tym przypadku programista mo\u017ce uzyska\u0107 dost\u0119p do metod z innych aplikacji w czasie kompilacji przy u\u017cyciu wszystkich zwyk\u0142ych \u015brodk\u00f3w, pod warunkiem, \u017ce s\u0105 one zadeklarowane jako <em>public<\/em>. W zwi\u0105zku z tym, w przypadku obs\u0142ugi b\u0142\u0119d\u00f3w podczas ewidencjonowania, niezmiennie obowi\u0105zuje zasada: tylko wtedy, gdy wszystkie u\u017cywane symbole i odniesienia mog\u0105 zosta\u0107 pomy\u015blnie rozwi\u0105zane, a nowo opracowana lub zmieniona klasa mo\u017ce zosta\u0107 skompilowana bezb\u0142\u0119dnie, jest ona zaewidencjonowana.<\/p>\n<p>Utworzone pliki <i>Java-class<\/i> zawieraj\u0105 w ten spos\u00f3b odniesienia do wywo\u0142ywanych metod innych aplikacji.<\/p>\n<p>W czasie dzia\u0142ania Java Virtual Machine (JVM) podczas pierwszego dost\u0119pu do innej klasy pr\u00f3buje ona za\u0142adowa\u0107 t\u0119 klas\u0119 do pami\u0119ci. Je\u017celi w trakcie tego procesu stwierdzone zostanie, \u017ce odpowiedni plik <i>class<\/i> nie jest dost\u0119pny, zg\u0142aszany jest wyj\u0105tek <i>NoClassDefFoundError-Exception<\/i>, kt\u00f3ry domy\u015blnie powodowa\u0142by ponowne uruchomienie serwera aplikacji.<\/p>\n<p>W zwi\u0105zku z tym nale\u017cy zapobiec pr\u00f3bie za\u0142adowania przez <i>JVM<\/i> nieistniej\u0105cej klasy. Mo\u017cna to zrobi\u0107 na dwa sposoby: za pomoc\u0105 \u015brodk\u00f3w Java lub za pomoc\u0105 API Comarch ERP Enterprise.<\/p>\n<ul>\n<li>W Javie wyj\u0105tek mo\u017ce zosta\u0107 przechwycony przez blok try-catch. Zapewnia to jednak najmniejsz\u0105 kontrol\u0119 nad przebiegiem programu, poniewa\u017c wyj\u0105tek pojawia si\u0119 tylko podczas rzeczywistej pr\u00f3by dost\u0119pu.<\/li>\n<li>Wi\u0119ksz\u0105 kontrol\u0119 oferuj\u0105 metody isAppInstalled, kt\u00f3rych mo\u017cna u\u017cy\u0107 do sprawdzenia w czasie wykonywania, czy \u017c\u0105dana aplikacja jest zainstalowana. W zale\u017cno\u015bci od wyniku, sekwencja programu mo\u017ce by\u0107 nast\u0119pnie specjalnie kontrolowana. Dost\u0119p do powi\u0105zanej aplikacji jest cz\u0119sto cz\u0119\u015bci\u0105 bloku instrukcji, np. z przygotowawczymi, niekrytycznymi wywo\u0142aniami metod, kt\u00f3re powinny zosta\u0107 ca\u0142kowicie pomini\u0119te, je\u015bli aplikacja nie jest zainstalowana.<\/li>\n<\/ul>\n<p>Klasa com.cisag.pgm.util.PluginUtility oferuje 2 metody isAppInstalled(..) z r\u00f3\u017cnymi sygnaturami:<\/p>\n<ul>\n<li>Static boolean isAppInstalled(String developmentPrefix, String appName)<\/li>\n<li>Static boolean isAppInstalled(CisModuleId)<\/li>\n<\/ul>\n<h6 id=\"przyklad\" ><span class=\"ez-toc-section\" id=\"Przyklad-2\"><\/span>Przyk\u0142ad<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Aplikacja App2 uzyskuje dost\u0119p do obiektu biznesowego z App1.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Package com.ado.ext.app.app2;\nimport com.cisag.pgm.util.PluginUtility;\nimport com.ado.ext.app.app1.obj.App1TestBO;\n:\nApp1TestBO b;\nif (PluginUtility.isAppInstalled(\"ado\", \"app1\")) {\nSystem.out.println(\"Start reading...\");\nb = App1TestBO.newTransientInstance();\nCisObjectIterator&lt;App1TestBO&gt; it = b.retrieve_instances();\nwhile (it.hasNext()) {\nb = it.next();\nSystem.out.println(\" warto\u015b\u0107: \" + b.getValue());\n}\n} else {\nSystem.out.println(\"Wtyczka nie zosta\u0142a zainstalowana\");\n}\n:<\/pre>\n<p>Deklaracja zmiennej App1TestBO b; nie generuje \u017cadnego kodu wykonywalnego i dlatego nie musi by\u0107 zagnie\u017cd\u017cana.<br \/>\nKod ten mo\u017cna skompilowa\u0107 w systemie deweloperskim tylko wtedy, gdy istnieje plik klasy com\/ado\/ext\/app\/app1\/obj\/App1TestBO.class, cz\u0119\u015bciowo z powodu linii b = App1TestBO.newTransientInstance();. W czasie wykonywania kod w instrukcji if mo\u017ce zosta\u0107 wykonany tylko wtedy, gdy dost\u0119pne s\u0105 r\u00f3wnie\u017c klasy mappera App1TestBO.<\/p>\n<h6 id=\"wytyczne-programistyczne\" ><span class=\"ez-toc-section\" id=\"Wytyczne_programistyczne\"><\/span>Wytyczne programistyczne<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p><strong>Dost\u0119pno\u015b\u0107 klas<\/strong><\/p>\n<p>Mo\u017cliwo\u015b\u0107 adaptacji istniej\u0105cych klas Java powinna zosta\u0107 zachowana z jak najmniejsz\u0105 liczb\u0105 ogranicze\u0144. Do adaptacji wymagane jest jednak, aby klasa mog\u0142a by\u0107 w pe\u0142ni kompilowana na danym systemie deweloperskim. Z tego wzgl\u0119du nale\u017cy wzi\u0105\u0107 pod uwag\u0119 kilka kwestii podczas uzyskiwania dost\u0119pu do powi\u0105zanych aplikacji, aby klasy pozosta\u0142y adaptowalne.<\/p>\n<p>Klasa z dost\u0119pem do powi\u0105zanych aplikacji mo\u017ce by\u0107 edytowana tylko w tych systemach deweloperskich, w kt\u00f3rych zainstalowane s\u0105 odpowiednie powi\u0105zane aplikacje. W przeciwnym razie klasa nie mo\u017ce by\u0107 w\u0142\u0105czona do zadania deweloperskiego, poniewa\u017c nie b\u0119dzie mo\u017cna jej ponownie zaewidencjonowa\u0107 z powodu b\u0142\u0119d\u00f3w kompilacji. Dotyczy to zar\u00f3wno klas dodanych r\u0119cznie, jak i automatycznie do zadania deweloperskiego.<\/p>\n<p><strong>Dostosowywanie klas Java<\/strong><\/p>\n<p>Problem mo\u017ce wyst\u0105pi\u0107 zawsze wtedy, gdy w systemie ni\u017cszego poziomu S2 ma zosta\u0107 zaadaptowana klasa A z systemu S1, kt\u00f3ra zawiera dost\u0119py do powi\u0105zanej aplikacji B. Zgodnie z za\u0142o\u017ceniem, aplikacja B musi by\u0107 dost\u0119pna w S1. Nie mo\u017ce to by\u0107 jednak wym\u00f3g w S2, zw\u0142aszcza je\u015bli w S2 maj\u0105 zosta\u0107 wprowadzone tylko adaptacje klasy A, kt\u00f3re nie maj\u0105 odwo\u0142a\u0144 do aplikacji B, a odnosz\u0105 si\u0119 wy\u0142\u0105cznie do standardowego kodu aplikacji.<\/p>\n<p>Nale\u017cy pami\u0119ta\u0107 o nast\u0119puj\u0105cych kwestiach, aby kod by\u0142 jak najbardziej elastyczny (&#8222;najlepsza praktyka&#8221;):<\/p>\n<ul>\n<li>Klasa <i>A<\/i> nie powinna miesza\u0107 dost\u0119pu do klasy <i>B<\/i> z <i>zaprzyja\u017anionej<\/i> aplikacji z rozbudowan\u0105 logik\u0105 w\u0142asn\u0105.<\/li>\n<li>Mo\u017cna to osi\u0105gn\u0105\u0107, na przyk\u0142ad, poprzez utworzenie oddzielnej klasy <i>A&#8217;<\/i>, kt\u00f3ra zawiera metody <i>Wrapper<\/i> dla faktycznego dost\u0119pu do <i>B<\/i>, podczas gdy logika w\u0142asna pozostaje w <i>A<\/i> i wywo\u0142uje metody <i>Wrapper<\/i> z <i>A&#8217;<\/i>.<\/li>\n<li>W ten spos\u00f3b klasa <i>A<\/i> mo\u017ce by\u0107 nadal dostosowywana i kompilowana w <i>S2<\/i>, podczas gdy <i>A&#8217;<\/i> musi by\u0107 dost\u0119pna w <i>S2<\/i> jedynie jako plik <i>class<\/i>.<\/li>\n<\/ul>\n<p>Dodatkowo nale\u017cy jawnie oznaczy\u0107 klas\u0119 <i>A&#8217;<\/i> adnotacj\u0105 <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">@UsesFriendApps<\/code>\u00a0jako adaptowaln\u0105 tylko warunkowo.<\/p>\n<p><strong>Klasy nieadaptowalne<\/strong><\/p>\n<p>Za pomoc\u0105 adnotacji <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">@UsesFriendApps<\/code> mo\u017cna bezpo\u015brednio okre\u015bli\u0107 w deklaracji klasy, \u017ce klasa ta uzyskuje dost\u0119p do powi\u0105zanej aplikacji. Wp\u0142ywa to przede wszystkim na decyzj\u0119, czy ta klasa mo\u017ce by\u0107 adaptowana. Konkretnie, adnotacja okre\u015bla, czy klasa Java mo\u017ce ewentualnie nie zosta\u0107 w\u0142\u0105czona do zadania deweloperskiego.<\/p>\n<p><span style=\"color: #000000;\">Klasa z adnotacj\u0105 mo\u017ce zawsze zosta\u0107 uwzgl\u0119dniona w zadaniu programistycznym, je\u015bli zosta\u0142a utworzona w bie\u017c\u0105cym systemie. Je\u015bli pochodzi z innego systemu, w\u0142\u0105czenie zale\u017cy od parametr\u00f3w adnotacji. Je\u015bli adnotacja zostanie u\u017cyta bez dalszych parametr\u00f3w (@UsesFriendApps class &#8230;), klasa mo\u017ce zasadniczo nie zosta\u0107 uwzgl\u0119dniona w zadaniu deweloperskim. Wyra\u017anie okre\u015blaj\u0105c u\u017cywane powi\u0105zane aplikacje, mo\u017cna zdefiniowa\u0107, kt\u00f3re aplikacje musz\u0105 by\u0107 zainstalowane w systemie programistycznym S2, aby klasa mog\u0142a by\u0107 nadal uwzgl\u0119dniona w zadaniu deweloperskim. Aby to zrobi\u0107, nale\u017cy okre\u015bli\u0107 aplikacje jako list\u0119 ci\u0105g\u00f3w w formacie <\/span><\/p>\n<p><span style=\"color: #000000;\"><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">&lt;prefiks deweloperski&gt;\/&lt;nazwa aplikacji&gt;&#8221;, np. @UsesFriendApps=({&#8222;ado\/app1&#8221;, &#8222;ado\/app3&#8221;}) class &#8230;.<\/div><\/section><\/span><\/p>\n<p><span style=\"color: #000000;\"><section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\"><b>Jest to niezale\u017cne<\/b> od deklaracji <i>zaprzyja\u017anionych<\/i> aplikacji w ramach bie\u017c\u0105cej grupy systemowej.<\/div><\/section><\/span><\/p>\n<p><strong><span style=\"color: #ff00ff;\"><span style=\"color: #000000;\">Dostosowywanie obiekt\u00f3w biznesowych<\/span><\/span><\/strong><br \/>\nJe\u015bli <i>obiekt biznesowy<\/i> zostaje zmieniony w zadaniu deweloperskim, to poprzez wywo\u0142anie <i>crtbo<\/i> dodawane s\u0105 do zadania deweloperskiego ewentualnie ju\u017c istniej\u0105ce klasy <i>Update<\/i>. U\u017cycie Persistence service\u00a0w klasach <i>Update<\/i> jest niedozwolone. Dotyczy to r\u00f3wnie\u017c zapytania poprzez <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">isAppInstalled(..)<\/code>: odpowiednia konstrukcja z zagnie\u017cd\u017conym dost\u0119pem do innej aplikacji nie mo\u017ce by\u0107 tutaj stosowana.<\/p>\n<p><span style=\"color: #000000;\"><strong>Ograniczenia dla parametr\u00f3w<\/strong><\/span><\/p>\n<p>W przysz\u0142o\u015bci oddzielne aplikacje b\u0119d\u0105 mog\u0142y korzysta\u0107 z oddzielnych bibliotek, w szczeg\u00f3lno\u015bci r\u00f3wnie\u017c z r\u00f3\u017cnych wersji tej samej zewn\u0119trznej biblioteki. W tym celu ka\u017cda aplikacja b\u0119dzie zarz\u0105dza\u0107 w\u0142asnym obszarem pami\u0119ci, w kt\u00f3rym jej biblioteki s\u0105 \u0142adowane lokalnie. Prowadzi to jednak do tego, \u017ce obiekty z dw\u00f3ch lokalnych bibliotek nie s\u0105 ze sob\u0105 kompatybilne. (Przyczyna techniczna: Java u\u017cywa w\u0142asnego <i>Classloader<\/i> dla ka\u017cdej aplikacji, a dwie klasy mog\u0105 by\u0107 na siebie mapowane tylko wtedy, gdy zosta\u0142y za\u0142adowane przez ten sam <i>Classloader<\/i>).<\/p>\n<p>Z tego powodu nale\u017cy unika\u0107 stosowania obiekt\u00f3w z <i>obcej<\/i> biblioteki jako parametr\u00f3w lub warto\u015bci zwracanych przez powi\u0105zan\u0105 metod\u0119.<\/p>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Odpowiednia walidacja nie odbywa si\u0119.<\/div><\/section>\n<h4 id=\"korzystanie-z-innych-interfejsow\" ><span class=\"ez-toc-section\" id=\"Korzystanie_z_innych_interfejsow\"><\/span>Korzystanie z innych interfejs\u00f3w<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Klasa com.cisag.pgm.appserver.CisModuleId zawiera metod\u0119, kt\u00f3rej mo\u017cna u\u017cy\u0107 do okre\u015blenia, czy aplikacja jest zainstalowana. To sprawdzenie mo\u017ce by\u0107 u\u017cywane przed u\u017cyciem niekt\u00f3rych interfejs\u00f3w API (wyszukiwania OQL, Resultsets). Oznacza to, \u017ce te interfejsy API mog\u0105 by\u0107 r\u00f3wnie\u017c u\u017cywane bez zale\u017cno\u015bci od instalacji.<br \/>\nJe\u015bli <em>id<\/em> jest <em>CisModuleId<\/em> sprawdzanej aplikacji, metoda instancji boolean isInstalled() dostarcza informacji, czy aplikacja mo\u017ce by\u0107 u\u017cywana. Metoda ta uwzgl\u0119dnia r\u00f3wnie\u017c klucz licencyjny aplikacji, ale nie ustawienia <em>Konfiguracj<\/em>i.<\/p>\n","protected":false},"author":28,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"class_list":["post-9679","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-interfejsy-techniczne"],"_links":{"self":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/ht_kb\/9679","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/ht_kb"}],"about":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/comments?post=9679"}],"version-history":[{"count":11,"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/ht_kb\/9679\/revisions"}],"predecessor-version":[{"id":39817,"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/ht_kb\/9679\/revisions\/39817"}],"wp:attachment":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/index.php\/wp-json\/wp\/v2\/media?parent=9679"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}