metoda Runtime.getRuntime().exec() przechwytująca command lin'a

0

Witamy wszystkich

Programuję swój program w języku JAVA, a mianowicie słownik, który skontaktuje się z bazą danych MYSQL.
W opcjach programu chcę stworzyć możliwość stworzenia samej bazy danych oraz tabel potrzebnych do projektu, które zostaną pobrane z pliku createBaza.sql.
Chciałbym uzyskać efekt w kodzie Java, który mogę uzyskać poprzez linię poleceń (cmd):

C:\> myql -u root -pMyPass < MyConfigFile.sql, która wstrzyknie do bazy danych polecenia pobrane z pliku MyConfigFile.sql, tutaj zawartość pliku createBaza.sql:

create database Music;
use Music;
create table MusicTable(name varchar(20) not null,autor varchar(20) not null);
grant all on *.* to yogi@localhost identified by 'babuuu' with grant option;

i utworzy bazę Music, tablice i user'a.

W javie napisałem formatkę z JButtonem, a po kliknięciu na przycisk wywołuje on metodę ActionListener() z Runtime.getRuntime().exec(), i chciałbym uzyskać efekt jak z linii poleceń czyli tworzenie bazy,tablic, użytkownika itp, tutaj 2 przykłady mojego kodu:

try {
           String command = "cmd /k start mysql -u root -pMyPassword < date.sql";
           process = Runtime.getRuntime().exec(command);
}catch(IOException exc){ JOptionPane.showMessageDialog(null,exc.getMessage()); }

oraz

File file = new File("C:/mysql/date.sql");
try {
      String command = "cmd.exe /k start mysql -u root -pMyPassword";
      Process process = Runtime.getRuntime().exec(command);
      BufferedReader reader= new BufferedReader(new FileReader(file));
      BufferedOutputStream writer = new BufferedOutputStream(new
      DataOutputStream(process.getOutputStream()));
      StringBuffer buffer = new StringBuffer();

         String line;
         while((line = reader.readLine()) != null){
                 buffer.append(line);
                 System.out.println("line = "+line);
         }
         writer.write(buffer.toString().getBytes());
         writer.flush();
         writer.close();

}catch(IOException exc){JOptionPane.showMessageDialog(null,exc.getMessage());}


Niestety moje próby nie przyniosły oczekiwanych rezultatów, ponieważ przedstawiony przeze mnie kod loguje się tylko do bazy danych MySql a chciałbym, aby przekierował polecenia z pliku MyConfigFile.sql, który utworzy bazę danych,tabele, usera.

Znalazł em rozwiązanie podobnego problemu pod adresem, ale niestety tam dane są zapisywane od strumienia do pliku, a w moim przypadku wygląda to odwrotnie.
I jeszcze jedno pytanie dotyczące linku, czy przykład z podlinkowanej strony musi wykorzystywać wielowątkowość aby działał, ja nie wykorzystałem tego mechanizmu ale nie sądzę aby tu tkwił problem, proszę o szczegółowe wyjaśnienia.

Jestem początkującym programistą, więc będę wdzięczny za wszelką pomoc.

Pozdrawiam.

1

Trochę nie rozumiem czemu chcesz tak zrobić zamiast bezpośrednio uderzyć z Javy do bazy danych?

0

No właśnie widzisz kolego ja wiem jak to zrobić z poziomu command lina, ale zakładam że program będzie używała osoba która nie ma o tym pojęcia i co wtedy,chciałbym aby klikała przycisk i wszystko robi się z automatu, a poza tym po prostu chciałbym wiedzieć czy to wykonalne, a jeśli tak to jak to zrobić :)
Pozdrawim

1
Little Programer napisał(a):

zakładam że program będzie używała osoba która nie ma o tym pojęcia i co wtedy

No właśnie dokładnie w tym celu powinieneś ukryć szczegóły implementacji, i wystawić temu komuś jakieś sensowne API swojej klasy / pakietu / programu ;)

0

Ta aplikacja i klika innych ma być dostępem do mojej wymarzonej pracy programisty, i boje się że panowie którzy to będą oceniać mimo że wiedzą co w trawie piszczy będą chcieli czegoś więcej, albo zadadzą mi takie pytanie a co jeśli osoba będzie niekumata i nie będzie potrafiła stworzyć bazy, tablic itd jak pan to rozwiąże jaki ma pan pomysł, może przesadzam ale po prostu boje się i ciągle mi się wydaje że nic nie umiem stąd pytanie aby wiedzieć wszystko bo inaczej mi się nie uda.
Pozdrawiam

0

Spokojnie xD powiedz nam jaki masz temat zadania to pomożemy

0

Ponawiam pytanie czy jest to wykonalne, a jeśli tak jak to zrobić ?

2
  1. To co robisz nie ma absolutnie sensu.
  2. Użyj JDBC, połącz sie do bazy bezpośrednio z tej javowej aplikacji i rób z tą bazą co chcesz.

Ta aplikacja i klika innych ma być dostępem do mojej wymarzonej pracy programisty,

To jeszcze bardzo daleko jesteś od poziomu pracy. Niewyobrażalnie daleko. Jakbyś coś takiego komuś pokazał to trafiłbyś do jakichś Perełek rekrutacyjnych po wsze czasy.

0

Jakbyś coś takiego komuś pokazał

to znaczy co dokładnie co?

Zapytałem czy to da się zrobić, po prostu chciałem się dowiedzieć czy istnieje taka możliwość.
Zadałem kilka pytań a w zamian dostałem , właściwie nie dostałem odpowiedzi.

Jakbyś coś takiego komuś pokazał to trafiłbyś do jakichś Perełek rekrutacyjnych po wsze czasy

To co według ciebie powinienem pokazać żeby nie trafić na te perełki ?
Tak jak napisałem powyżej w linku gdzie znalazłem podobną sytuacje facet z poziomu aplikacji robił zrzut bazy
nie podłączał się przez sterownik JDBC tylko z poziomu aplikacji:

String[] command = new String[] {"cmd.exe", "/c", "C:/mysql/mysqldump.exe" --quick --lock-tables --user=\"root\" --password=\"mypwd\" mydatabase > \"C:/mydump.sql\""};
Process process = Runtime.getRuntime().exec(command);
int exitcode = process.waitFor();

a ja chciałem się dowiedzieć czy istnieje taka możliwość, ale dla odwrotnej sytuacji czyli przekazaniu danych do process'u z Runtim'a, i gdzie popełniłem błąd.Dzięki temu czegoś nowego się nauczę..
Czy to przestępstwo chcieć się czegoś dowiedzieć ?

1
Little Programer napisał(a):

chciałem się dowiedzieć czy istnieje taka możliwość

W programowaniu w javie można praktycznie wszystko. Pytanie, czy java jest sensownym narzędziem do wszystkich problemów - w końcu można także koparką wykopać malutki dołek, jeśli się jest dostatecznie dokładnym. Ale nie o to chodzi, to nie to narzędzie do tej klasy problemu. I chyba o to chodziło @Shalom -owi

3

Zadałem kilka pytań a w zamian dostałem , właściwie nie dostałem odpowiedzi.

Bo robisz tu klasyczny http://xyproblem.info/ taką wręcz książkową wersje. Pytasz jak zrobić Y, podczas gdy w rzeczywistości chcesz zrobić X, a Y jest tylko twoim (bardzo złym i błędnym) pomysłem na osiągnięcie X.

podobną sytuacje

Sytuacja z linka jest ZUPEŁNIE NIEPODOBNA. Tam ktoś chce zrobić dump bazy i tego w niektórych bazach nie da się łatwo zrobić za pomocą zwykłego zapytania do bazy, stąd też pomysł żeby użyć aplikacji do tego przeznaczonej i wywołać ją przez system/exec. Twoja sytuacja nie ma z tym NIC WSPÓLNEGO. Ty chcesz normalnie z tej bazy korzystać.

To co według ciebie powinienem pokazać żeby nie trafić na te perełki ?

Jeszcze raz: lekcja na dziś JDBC https://docs.oracle.com/javase/tutorial/jdbc/index.html

a ja chciałem się dowiedzieć czy istnieje taka możliwość, ale dla odwrotnej sytuacji czyli przekazaniu danych do process'u z Runtim'a, i gdzie popełniłem błąd.Dzięki temu czegoś nowego się nauczę.. Czy to przestępstwo chcieć się czegoś dowiedzieć ?

W sumie co mi tam, to z ciebie zrobią pośmiewisko, nie moja sprawa. Odpowiedź brzmi: tak, da sie, ale nie używaj do tego Runtime.exec bo ono jest mocno ograniczone. Użyj klasy ProcessBuilder https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/ProcessBuilder.html ona pozwala na interakcje z tym utworzonym procesem, czytanie z jego wyjścia i pisanie na wejście. Nie robisz tam żadnego przekierowania, tylko odpalasz proces, a następnie pobierasz sobie stream i do niego piszesz zawartość tego twojego pliku z sqlem.

Mała analogia to co robisz to mniej więcej taki poziom: Ktoś poprosił cię o zrobienie screenshota ekranu a ty wyciągnąłeś aparat dziadka z kliszą, zrobiłeś zdjęcie monitora a teraz pytasz nas gdzie można to zdjęcie wywołać, a potem planujesz wysłać to zdjęcie pocztą.
Faktycznie, z pewnego punktu widzenia to jest poprawne rozwiązanie - odbiorca faktycznie będzie mógł zobaczyć co miałeś na ekranie...

0

Pinek i Shalom dziękuję wam bardzo za odpowiedź właśnie o to mi chodziło.
Napisałem sobie aplikacje słownik do nauki słówek z angielskiego wykorzystałem do tego JDBC, wszystko działa nawet uczę się z tego programiku.
Ale wpadł mi do głowy taki pomysł, żeby z automatu skonfigurować bazę pod aplikacje, no i się zaczęło zacząłem kombinować :).
Dziękuję bardzo za pomoc i wyjaśnienia ;)

1
Little Programer napisał(a):

Pinek i Shalom dziękuję wam bardzo za odpowiedź właśnie o to mi chodziło.
Napisałem sobie aplikacje słownik do nauki słówek z angielskiego wykorzystałem do tego JDBC, wszystko działa nawet uczę się z tego programiku.
Ale wpadł mi do głowy taki pomysł, żeby z automatu skonfigurować bazę pod aplikacje, no i się zaczęło zacząłem kombinować :).
Dziękuję bardzo za pomoc i wyjaśnienia ;)

Jak chcesz "bezstressową" bazę do konkretnego programu, to embedded. Na MySQL się branża nie kończy, np H2 albo Derby. Albo nie SQLowa, tylko jakaś key-value, jak się obudzę to podam jakieś nazwy ;)

Zgadzam się, że wytworzyłeś XY problem. Prawidłowe pytanie by było o bazę zero-instalation-and-configuration

0

Witam wszystkich
Widzisz AntyKtokolwiek Shalom napisał :

"To co robisz nie ma absolutnie sensu."

a ja cały czas myślę dlaczego?, czy chodziło mu o to, że sama koncepcja automatyzowania utworzenia bazy jest bez sensu, a może sposób

w jaki chciałem to osiągnąć bezsensowny. Powiem Ci szczerze, że dziś rano się obudziłem i znowu zaczłąm o tym myśleć, to nie daje mi
spokoju.

Pinek napisał zresztą bardzo mu za to dziękuję:

"Pytanie, czy java jest sensownym narzędziem do wszystkich problemów - w końcu można także koparką wykopać malutki dołek, jeśli
się jest dostatecznie dokładnym. Ale nie o to chodzi, to nie to narzędzie do tej klasy problemu. I chyba o to chodziło @Shalom -owi".

Tak jak pisałem jestem początkujący dla Shalom'a i Pink'a którzy mają dużą wiedzę wydaje się to głupotą dla mnie na tamtą ale i na

razie na tą(bo nieznam innego sposobu) chwilę był to jedyny pomysł(na konfigurację o instalacji nawet nie myślę).
Więc jeśli tak jak napisał Pinek:

"to nie to narzędzie do tej klasy problemu"

to jakiego powinienem użyć, i czy mój pomysł był wykonalny mimo że archaiczny ?.
AntyKtokolwiek napisałeś:

"Zgadzam się, że wytworzyłeś XY problem. Prawidłowe pytanie by było o bazę zero-instalation-and-configuration"

no właśnie masz racje pomyślałem sobie że to trochę bez sensu tworzyć przycisk do konfiguracji bazy której ja sam nie instalowałem,
ale widzisz z moją wiedzą i umiejętnościami ten pojedynczy skrypt konfiguracji to mały klocuszek a napisanie całej instalacji i
konfiguracja to za wysokie progi stąd pomysł by zacząć od czegoś malutkiego, tak się uczę poznaję małe klocuszki i łącze je w coraz
to większy domek ;), po prostu chodzi mi o to czy mój tok rozumowania był prawidłowy skąd moje rozumowanie, skoro w cmd po wykonaniu polecenia:

"cmd.exe", "/c", "C:/mysql/mysqldump.exe" --quick --lock-tables --user=\"root\" --password=\"mypwd\" mydatabase > \"C:/mydump.sql\""};

zrzucam bazę do pliku, i tak jak we wcześniej przeze mnie podlinkowanej stronie, gościu zrobił w kodzie java za pomocą Runtime'a :

String[] command = new String[] {"cmd.exe", "/c", "C:/mysql/mysqldump.exe" --quick --lock-tables --user=\"root\" --password=\"mypwd\"  mydatabase"};

czyli wywołanie damp'a z parametrami który przekazuje strumień danych w tym przypadku do Klasy Process(rozumiem że jest to instancja dampa wywołanego przez cmd) jak poniżej:

Process process = Runtime.getRuntime().exec(command);

Ten process a własciwie strumień danych z damp'a zostały opakowany w Klase BufferedReader

BufferedReader input = new Buffered Reader(newInputStreamReader(process.getInputStream()))

a później w pętli przechwycony i zapisany do pliku jako kopia.sql. A ja w dokumentacji klasy Process przeczytałem że daje on dostęp do 3 strumieni:

All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via
the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream().

"mysqldump.exe --quick --lock-tables --user=\root\ --password=mypwd mydatabase > C:/mydump.sql\";
"mysql -u root -phasło < plik.sql"

Więc skoro za pomocą jav'owej metody getInputStream(), Strumienia i pętli mogę pozyskać dane z damp.exe i zapisać poprzez aplikacjie java do pliku.sql, to na moje oko wygląda to podobnie do shell'a tylko realizuje to poprzez Javę, to dlaczego nie można by tak samo wrzucić danych z pliku configBaza.sql do mysql, poprzez aplikację java za pomocą getOutputStream()(pomijając ograniczone możliwości tego polecenia, o którym pisał Shalom), przecież shell wykonuje podobną(tak mi się wydaje może się mylę) operację w jednym i drugim przypadku.
Chodzi mi o sam fakt czy moje rozumowanie jest właściwie, i teraz wszyscy co dotarli aż do tego momentu szanuje wasz czas i nerwy dlatego odpowiedzcie mi:

a.Nie, nie wykonasz tym sposobem konfiguracji bazy z poziomu javy, bo twój tok rozumowania jaki i wykorzystane narzędzie runtime.getRuntime().exec() nie wykonało by tego zadania.

b.Tak twój tok rozumowania jest właściwy ale metoda runtime.getRuntime().exec() jest zbyt ograniczona do tego typu zadań, wykorzystaj ProcessBuilder'a o którym pisał Shalom, jednak tak czy siak jest to przestarzałe rozwiązanie.

Ps. Proszę napiszcie mi coś o właściwych sposobach konfiguracji bazy MySql poprzez kodowanie w jav'ie jakie mam opcje,narzędzia itd.

1

Opcja d) Wywoływanie zewnętrznych programów z poziomu twojego kodu to bardzo niebezpieczna, powolna i jednocześnie strasznie zawodna metoda na osiągnięcie czegokolwiek. Ot choćby wymagasz żeby użytkownik twojego programu posiadał plik mysqldump.exe, mógł go w ogóle odpalić, żeby ściezki sie zgadzały itd. Robi się tak tylko i wyłącznie kiedy faktycznie musisz i nie ma innej metody. W twoim przypadku to strzelanie z armaty do muchy. Trochę jak w kawale:

- Janie, przynieś mi fortepian! 
- Będzie jaśnie Pan grał? 
- Nie, tam leży moja fajka.

Ps. Proszę napiszcie mi coś o właściwych sposobach konfiguracji bazy MySql poprzez kodowanie w jav'ie jakie mam opcje,narzędzia itd.

Możesz zawsze wziąć jakiegoś Spring Boota i tam konfiguracja bazy i ładowanie początkowego stanu załatwi ci ustawienie kilku property. Ale nie teraz. Teraz jesteś na poziomie hello world i niepotrzebnie zabierasz sie nawet za takie tematy jak baza danych w ogóle.

0

Shalom dzięki za odpowiedź.
Ale powiem ci jedno skoro na podstawie jednego pytania jakie zadałem od razu potrafisz bezbłędnie określić moją ogólną wiedzę to może zagraj w totka a zostaniesz milionerem.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1