VisualVM Java IDE wars plugin
Pobierz :
- NetBeans IDE 6.1 ub 6.5
- Visual VM .
Potrzebny będzie również kod źródłowy gry Shootout autorstwa Dawida Weissa, orginalna wersja nie pozwalała na osadzenie gry w kontenerach Swingowych, musiałem więc wprowadzić kilka poprawek
. Kod źródłowy dostępny jest tutaj. Aby zbudować jar’a wystarczy rozpakować archiwum i w katalogu shootout wydać polecenie: ant jar-netbeans w shootout/build znajdziecie finalnego jar’a.
Po zainstalowaniu Visual VM (można też użyć tego który znajduje się w Waszym JDK) i uruchomieniu NetBeans IDE możemy przystąpić do pracy. W niektórych miejscach korzystałem z wizardów NetBeansowych więc samo spojrzenie w kod tych próbek może nie dać wam pełnego obrazu jak najszybciej dojść do finalnego efektu
Visual VM to aplikacja stworzona w oparciu o NetBeans Paltform, przeglądając zawartość folderu aplikacji możecie natknąć się na charakterystyczne dla aplikacji NBP nazwy plików i katalogów. Zanim zaczniemy właściwą pracę musimy zarejestrować instację platformy NB, która znajduje się w Visual VM. Oprócz standardowych elementów NB są tam również moduły specyficzne dla Visual VM jak np. VisualVM-Application czy VisualVM-Core.
Aby zarejestrować instancje platformy należy wybrać z menu Tools>NetBeans Plaform i dodać nową platformę (przycisk Add Platform) – wskazujemy na katalog w którym został zainstalowany VisualVM
Rejestracja platformy umożliwi nam nie tylko zapewnienie pełnej zgodności z platformą na której uruchamiany będzie plugin, ale pozwoli również na debugowanie i szybkie uruchamianie tworzonego przez nas rozszerzenia w docelowym środowisku.
Tworzymy nowy projekt wybierając File>New Project>NetBeans Modules i z listy o prawej stronie wybrać Module Suite klikamy Next.
W następnym kroku kreatora wpisujemy nazwę projektu i wybieramy platformę w oparciu o którą będziemy rozwijali nasz zestaw modułów. W poprzednich krokach zarejestrowaliśmy instancję należącą do Visual VM i to właśnie ją wybieramy z listy rozwijanej.
Module Suite jest kontenerem dla modułów które są z jakichś względów są ze sobą powiązane, w wyniku naszych działań powstaną dwa moduły: właściwa wtyczka do VisualVM i drugi będący owijką na shootout.jar. Dlaczego tak? Scenariusz jest bardzo prosty wyobraźcie sobie, że została wydana nowa wersja Shooout i chcielibyśmy mieć ją w naszej wtyczce. Po dokonaniu niezbędnych zmian przez nas, użytkownicy wtyczki musieliby ściągać nie tylko nową wersję gry, ale i samą wtyczkę, którą już przecież mają. Aby więc w pełni wykorzystać zalety modułowości każda biblioteka wykorzystywana przez naszą wtyczkę powinna zostać opakowana w pewne dodatkowe informacje, które pozwolą instancji NetBeans Platform na aktualizację tylko tej konkretnej biblioteki.
Czas więc stworzyć Library Wrapper Module dla Shootout.jar. Klikamy File>New Project>NetBeans Module>Library Wrapper Module w pierwszym kroku kreatora trzeba podać ścieżkę do pliku jar, który opakowujemy i do pliku z licencją na której biblioteka jest/ma być udostępniania. W ostatnim kroku kreatora pojawia się pytanie o codebase, wpisujemy com.dawidweiss.shootout.
O czym jeszcze warto wspomnieć, pierwotnie Shootout.jar miał w manifeście ustawiony parameter Main-Class, który wskazywał na klasę posiadającą metodę main w której uruchamiana była gra. Powodowało to, że wtyczka po umieszczeniu w VisualVM nie działała. Wywalenie tego atrybutu z manifestu załatwiło sprawę. Niestety nie znam się na wnętrznościach NetBeans Platform więc nie jestem w stanie tego sobie wytłumaczyć bardziej racjonalnie.
Zależności w formie LWM mogą być deklarowane przez wszystkie moduły wchodzące w skład nadrzędnego Module Suite.
Mamy już jeden moduł, teraz czas przejść do najważniejszej części tego artykułu – tworzenia właściwej wtyczki do VisualVM.
Tworzymy nowy projekt File>New Project>NetBeans Module>Module, moduł powinien zostać dodany do stworzonego wcześniej Module Suite. W kolejnym kroku wpisujemy codebase : org.grejpfrut.vvm, w NetBeans 6.5 wpisanie poprawnego codebase uzupełnia również pozostałe pola formularza.
Kolejny krok to dodanie zależności, w oknie Projects klikamy prawym na węzeł reprezentujący moduł i wybieramy Properties. Następnie zakładka Libraries musimy mieć zadeklarowane następujące zależności: Module System API, shootout, Utilities API, VisualVM-Application i VisualVM-Core.
W oknie Projects klikamy prawym przyciskiem myszy na węzeł reprezentujący stworzony przed chwilą moduł i wybieramy New>Module Installer. Stworzona klasa Installer i jej dwie metody restored i uninstalled umożliwiają nam wpięcie się w cykl życia tworzonej właśnie wtyczki. Kod z metody restored jest wykonywany w chwili załadowania modułu, jest to najwłaściwsze miejsce aby zarejestrować klasy implementujące rozszerzenia. Natomiast metoda uninstalled jest wywoływana w momentcie gdy moduł jest usuwany ze środowiska lub gdy jest ono wyłączane.
public class Installer extends ModuleInstall {
@Override
public void restored() {
FirstExamplePluginViewProvider.initialize();
}
@Override
public void uninstalled() {
FirstExamplePluginViewProvider.unregister();
}
}
W mojej prezentacji z NetBeans Day możecie znaleźć krótkie omówienie tego co można rozszerzyć w VisualVM, więcej o tym piszę Geertjan w
dokumentacji VisualVM i na swoim blogu. FirstExamplePlugin będzie tworzył dodatkową zakładką, którą użytkownicy będą mogli zobaczyć po połączeniu się do jakiegoś JVMa. W zakładce tej będą się działy rzeczy różne
.
Należy teraz stworzyć klasę FirstExamplePluginViewProvider, jak sugeruje nazwa, klasa ta będzie odpowiedzialna za “produkcję” instancji klasy FirstExamplePluginView.
class FirstExamplePluginViewProvider extends DataSourceViewProvider {
//prosty singleton
private static DataSourceViewProvider instance = new FirstExamplePluginViewProvider();
static void initialize() {
//rejestrujemy instancję FirstExamplePluginViewProvider w zarządcy widoków
DataSourceViewsManager.sharedInstance().addViewProvider(instance, Application.class);
}
static void unregister() {
//wyrejestrowujemy instancję FirstExamplePluginViewProvider w zarządcy widoków
//metoda jest wywoływana podczas odinstalowywania modułu i wyłączania środowiska
DataSourceViewsManager.sharedInstance().removeViewProvider(instance);
}
@Override
protected DataSourceView createView(Application app) {
//tworzy instancję widoku
return new FirstExamplePluginView(app);
}
}
Klasa ta to prosty singleton, który w czasie inicjalizacji modułu (initialize) dodaje do DataSourceViewManager’a swoją instancję. Najważniejszą metodą w tej klasie jest createView, która to tworzy naszą zakładkę.
Kopiując poniższy kod należy pamiętać o wskazaniu poprawnej ścieżki do ikonki wyświetlanej w etykiecie zakładki:
org/grejpfrut/vvmnbd/example/grejpfrut.png – szczegóły będą widoczne w źródłach.
public class FirstExamplePluginView extends DataSourceView {
private DataViewComponent dvc;
//sciezka do ikony, ktora bedzie wyswietlana w zakładce zakładki
public final static String IMAGE_PATH = "org/grejpfrut/vvmnbd/example/grejpfrut.png";
public FirstExamplePluginView(Application app) {
//tytuł zakładki i ikona
super(app, "Java IDE wars plugin", new ImageIcon(Utilities.loadImage(IMAGE_PATH)).getImage(), 3, true);
}
@Override
protected DataViewComponent createComponent() {
//tworzenie elementów widoku
JEditorPane generalDataArea = new JEditorPane();
generalDataArea.setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));
JPanel details1Panel = new JPanel(new BorderLayout());
ShootoutBoard board = new ShootoutBoard(new ShootoutUtilities().getEnemyFactory(), details1Panel);
details1Panel.add(board, BorderLayout.CENTER);
details1Panel.setBackground(Color.GRAY);
details1Panel.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
//osadzanie stworzonych kontrolek w kontenerze VisualVM
DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("Java IDE wars plugin", null, generalDataArea);
//konfiguracja widoku
DataViewComponent.MasterViewConfiguration masterViewConfiguration = new DataViewComponent.MasterViewConfiguration(false);
//tworzymy właściwy komponent, który bedzie wyswietlany w VVM
dvc = new DataViewComponent(masterView, masterViewConfiguration);
//tworzymy panel z planszą gry
DataViewComponent.DetailsView details = new DataViewComponent.DetailsView("", "Detale tego okienka", 10, details1Panel, null);
//umieszczamy go w odpowiednim miejscu
dvc.addDetailsView(details, DataViewComponent.TOP_LEFT);
//gra ma być domyślnie ukryta
dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);
return dvc;
}
}
Po uzupełnieniu importów, możemy uruchomić nasz plugin aby tego dokonać należy w oknie Projects kliknąć prawym na węzeł reprezentujący nasz Module Suite i wybrać “Run” lub “Debug”. NetBeans uruchomi teraz nasz plugin w platformie która wybraliśmy dla naszych modułów. Teraz klikamy w dowolny proces JVM, który jest wyświetlany na drzewku Applications i powinna się naszym oczom ukazać zakładka z grejpfrutem, po kliknięciu “Details” powinna już rozpocząć się strzelanina
.

Kompletne źródła już wkrótce, po tym jak skończe drugą cześć “Własny ApplicationType”.
Wszystko oparte na serii artykułów Getting Started Extending VisualVM autorstwa Geertjana Wielengi.