Keresés

Új hozzászólás Aktív témák

  • Mr K

    őstag

    válasz #68216320 #10800 üzenetére

    Az exe futtatása megoldható a Runtime.getRuntime().exec(...) hívással. Visszakapsz egy processz-t, aminek a lefutását waitFor()-ral megvárod. Itt van rá egy kis példa program, ami már demonstrálja azt is, hogy hogyan lehet az exe outputját (stdout) megszerezni. (Alternatíva, hogy az exe egy fájlba írja az outputját, amit futás után normál módon fájlként felolvasol.)

    A parsolásra régebben még azt mondtam volna, hogy kell írni egy parsert, de manapság ez nem divat... Ha tényleg ennyire rögzített a szerkezet, akkor a sorban szereplő négy komponens (csoport, adatnév, értéknév, érték) előbányászható egy reguláris kifejezéssel is, pl. ezzel:

    ^([^.]+)\.([^.]+)\.([^.]+): *(.*?) *$

    Az outputot soronként célszerű feldolgozni, az elején vagy ki kell hagyni fix számú sort, vagy egyszerűen ki kell hagyni azokat, amire nem illeszkedik a regex:
    Pattern pattern = Pattern.compile(<a fenti regex>);
    while (<van sor>) {
    Matcher m = pattern.matcher(<a sor tartalma>);
    if (m.find()) {
    String sensorGroup = m.group(1);
    // ...
    String sensorValue = m.group(4);
    // DB mentés
    }
    }

    Alternatív szervezés: linux-ban oldod meg, amit lehet. A java program nem hajt végre exec-et, helyette a standard input-ot olvassa, és dolgozza fel. Hívni meg valahogy így:

    >sensor.exe <opciók> | java -jar sensorprocessor.jar

    És az egészet lehet futtatni pl. cron-ból. (Hátránya, hogy a JVM indítás kissé erőforrásigényes, 30 másodpercenként meg pláne.)

    Megjegyzések: (1) fejből írtam, a kódot tekintsük pszeudokódnak, (2) a regex pattern-ben a \-eket duplikálni kell a Java string konstansban.

    Szerk: A korábbi válaszokat nem láttam, pár dolog így ismétlés, bocs.

  • Mr K

    őstag

    válasz Zsoxx #10773 üzenetére

    A praxisomban ilyesmivel még nem találkoztam. Standard nyelvi eszközről nem tudok (legalábbis Java 8-ig bezárólag) - ettől persze még létezhet. A probléma viszont nyilván nem megoldhatatlan. Az első lehetőség a java fordító meghívása (lásd az előző hozzászólást), majd a gyártott osztály dinamikus betöltése (mint a JDBC driver-nél) és végrehajtása. Lásd pl. itt. Ennél a megoldásnál az a korlát, hogy a fordítási egység az osztály. A másik lehetőség, ami eszembe jut, a byte kód manipuláció (bytecode instrumentation), amivel lehet turkálni a már lefordított osztályok belsejében (új eljárásokat hozzáadni, meglévőeket kiegészíteni, stb.) Lásd pl. itt. Elképzelhető, hogy vannak ezekre alapozva kész megoldások is, bár én egy gyors kereséssel nem találtam ilyet.

    Én nem vetném el teljesen a script nyelveket sem. (Bár nem tudom, hogy pontosan mi a feladat... :) ) A Groovy nagyjából felülről kompatibilis a Javával (azaz a Java forráskód érvényes Groovy forráskód is), legalábbis kb. a 7-es nyelvi szintig, bár a szemantikában vannak apróbb eltérések. A script nyelvek és a java kölcsönösen hívhatják egymást (azaz egy programon belül keverhetők). A script nyelvek mellett szól még, hogy tömörebbek (elhagyhatók a változó deklarációk, stb.), azaz pár soros kódokhoz alkalmasabbak.

  • Mr K

    őstag

    válasz Zsoxx #10770 üzenetére

    Ha stringben tárolt programot (script-et) szeretnél futtatni, arra is van számtalan script nyelv, pl. a Groovy (java-szerű), a Jython (Python) vagy akár a Javascript.

  • Mr K

    őstag

    válasz Szmeby #10767 üzenetére

    Az "Ez inkább javallott, mint a finalize() funkció használata." mondatot értelmeztem úgy, hogy a finalize is javallott, csak kevésbé. :)

  • Mr K

    őstag

    válasz Szmeby #10764 üzenetére

    A finalize általában nem fog működni:
    public class T {
      static void p(String msg) { System.out.print(msg); }
      public static void main(String[] args) {
      p("started"); T t = new T(); t = null; p(" finished");
      }
      private T() { p(" constructed"); }
      @Override protected void finalize() { p(" finalized"); }
    }

    (Kimenet: started constructed finished)

    Ha a teszt JVM-emen beszúrok egy GC-t, akkor javul a helyzet:
        p("started"); T t = new T(); t = null; System.gc(); p(" finished");
    (Kimenet: started constructed finished finalized)

    De azon túl, hogy egy normális programot nyilván nem lehet telehinteni GC hívásokkal, az egész viselkedés még a garbage collector implementációjától is függ, szóval a finalize egyáltalán nem megoldás a problémára.

  • Mr K

    őstag

    válasz Keem1 #10761 üzenetére

    Destruktor nincs. Finalizálás van, de az a garbage collector futásához kapcsolódik, és nincs garancia arra, hogy egy adott objektum esetén valaha is lefut - program exit-kor meg pláne, hiszen akkor majd az oprendszer úgyis takarít...

    Nem teljesen értem, hogy minek az exit hook. Egy java programnak jól meghatározott exit pontjai vannak: pl. a main() return pontja, vagy a System.exit() hívás, ezért ha kilépéskor akarsz menteni, akkor ezek elé kell elhelyezni a megfelelő kódot. Ha a program interaktív, akkor nyilván lesz valahol egy "exit" menüpont, vagy window close hook, ahová a mentés ugyancsak beköthető. Ha valamilyen egyéb keretrendszert használsz (pl. servlet engine), ami saját maga intézi a startup és shutdown tevékenységet, akkor ott lesznek specifikus exit hook-ok (pl. a servletnek van init() meg destroy() eljárása, vagy ott a ServletContextListener).

    Mint arra fentebb már felhívták a figyelmet, ha a program abnormális módon terminál (kilövik az oprendszerből, vagy pl. OutOfMemoryError kivétel keletkezik), akkor semmilyen exit hook nem fog működni. Ha erre is fel szeretnél készülni, akkor érdemesebb inkább minden alkalommal automatikusan menteni, ha az ini fájlban tárolt adatok változnak. (És ebben az esetben a kilépéskori mentés eleve felesleges is.) Persze nem tudom mi lenne itt az adatkör: az inicializációs fájl mint fogalom, néhány kilobájtnyi ritkán változó adatot sugall.

  • Mr K

    őstag

    válasz Taoharcos #10749 üzenetére

    Ha van olyan oszlophalmaz, amiből lehet kulcsot képezni (azaz pl. lehet(ne) rájuk unique indexet definiálni az adatbázisban), akkor az ezen oszlopoknak megfelelő objektumváltozóból lehet összetett kulcsot (composite key) gyártani. (Pl. az @EmbeddedId annotációval.)

    Ha Oracle az adatbázis, akkor lehet próbálkozni azzal is, hogy a ROWID-et rámapeljük valamilyen dummy változóra:
    @Id @Column(name="ROWID") String id;
    (Magam sohasem próbáltam, de lekérdezésnél akár működhet is... :) Persze a hordozhatóságnak ilyenkor annyi.)

Új hozzászólás Aktív témák

Hirdetés