web-dev-qa-db-fra.com

Communication entre deux applications de bureau Java Java distinctes)

Je cherche à développer deux applications de bureau séparées (mais liées) Java.

Je veux que l'une des applications puisse déclencher l'autre, en transmettant des données qui peuvent ensuite être éditées et retransmises, c'est-à-dire que la communication sera bidirectionnelle. Si l'autre application est déjà en cours d'exécution, je veux simplement qu'ils communiquent, c'est-à-dire que je ne veux pas simplement passer des arguments sur la ligne de commande, etc.

De manière générale, quelles stratégies/techniques dois-je envisager pour y parvenir?

44
William

Pour montrer à quel point il est facile de laisser deux applications communiquer entre elles, consultez cette démonstration du presse-papiers réseau à l'aide de JGroups. Il suffit de démarrer deux instances et de commencer à déposer des fichiers dans l'une d'elles. La deuxième instance affichera instantanément les mêmes fichiers.

import Java.io.Serializable;
import Java.awt.*;
import Java.awt.datatransfer.*;
import javax.swing.*;
import org.jgroups.*;

public class JGroupsTest {

    public static void main(String[] args) throws Exception {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(500, 300);
        final DefaultListModel listModel = new DefaultListModel();
        final JList panel = new JList(listModel);
        panel.setBackground(new Color(128, 0, 40));
        panel.setForeground(new Color(240, 240, 240));
        frame.add(panel);
        System.setProperty("Java.net.preferIPv4Stack", "true");
        final JChannel channel = new JChannel("udp.xml");
        channel.connect("networkclipboard");
        channel.setReceiver(new ReceiverAdapter() {
            @Override
            public void viewAccepted(View newView) {
                frame.setTitle("Network Clipboard - " + channel.getLocalAddress());
            }

            @Override
            public void receive(Message msg) {
                listModel.addElement(msg.getObject());
            }
        });

        panel.setTransferHandler(new TransferHandler() {
            @Override
            public boolean importData(JComponent comp, Transferable t) {
                DataFlavor[] transferDataFlavors = t.getTransferDataFlavors();
                for (DataFlavor flavor : transferDataFlavors) {
                    try {
                        Object data = t.getTransferData(flavor);
                        if (data instanceof Serializable) {
                            Serializable serializable = (Serializable) data;
                            Message msg = new Message();
                            msg.setObject(serializable);
                            channel.send(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return super.importData(comp, t);
            }

            @Override
            public boolean canImport(TransferSupport support) {
                return true;
            }

            @Override
            public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
                return true;
            }

        });
    }

}
22
mhaller

Cela dépend de la façon dont vous souhaitez communiquer ces 2 programmes:

  • Si vous n'avez besoin que de sémaphores interprocessus, créez un fichier quelque part dans/tmp et verrouillez-le.

  • Si vous avez uniquement besoin de la messagerie synchrone interprocessus (appel de procédure distante), RMI devrait être plus simple.

  • Si vous avez besoin d'une messagerie interprocessus asynchrone, JMS devrait être plus simple.

  • Si vous avez besoin de mémoire partagée interprocessus, utilisez des fichiers mappés.

  • Si vous avez besoin de tout ce qui précède, Terracotta (http://www.terracotta.org/) est le moyen le plus simple: Java sur différentes machines virtuelles Java sur le même ou même des ordinateurs différents se voient comme s'ils ont été exécutés à l'intérieur d'une machine virtuelle Java sur une machine. La division d'un programme en quelques-uns ne nécessite même pas de modifications de code - il suffit d'écrire un fichier de configuration XML.

19
iirekm

Ils pouvaient chacun écouter sur un Socket . Ce tutoriel est bon pour commencer.

18
BalusC

Vous devriez également considérer le bon vieux RMI classique.

8
Jé Queue

Jetez un œil à JavaGroups , cela résoudra votre problème de communication et vous aidera également à détecter si l'autre application est en cours d'exécution. Si l'application ne fonctionne pas, vous devrez lancer une nouvelle JVM pour elle avec Java.lang.Runtime.exec () ...

6
pgras

Essayez de communiquer avec SocketCommunication, même si l'application se trouve sur la même machine.

Vous trouverez ici plus d'informations sur comment faire (documentation Sun/Java).

4
osanchezmon
  • La voie à suivre "Entreprise" serait d'exécuter ces applications dans un Java EE ou au moins dans un framework Spring. C'est aussi probablement largement exagéré.

  • Si un tas de données doit être communiqué, RMI le fera.

  • Si vous n'avez pas peur de pirater votre propre protocole, structure de données et gestion des erreurs, vous pouvez configurer des sockets serveur et client et communiquer via ceux-ci.

  • Je pense qu'il y a un certain appel grossier à l'alternative de communiquer via un fichier dans un répertoire commun (configuration de votre propre protocole de qui écrit ou efface le fichier quand), ou via une base de données partagée. Low-tech, pas extrêmement rapide, mais très simple et fiable. Et il est assez facile de surveiller la "communication" de l'extérieur.

4
Carl Smotricz

Pour simplifier les choses, pourquoi ne pas simplement utiliser des sockets simples TCP?

2
Mark

Je seconde communication Socket et RMI. RMI est un peu plus impliqué mais plus intuitif pour un programmeur. Cela dépend du type d'informations que vous envoyez. Pousser des octets bruts sur une autre machine pourrait être plus logique que d'exécuter le serveur RMI et de gérer tout ce jazz ...

1
0x808080

Cela dépend du type de communication que vous souhaitez faire entre les 2 applications. Si vous utilisez des sockets ou RMI par exemple, les deux applications doivent être actives pour que la communication se fasse. Si le type de communication que vous souhaitez effectuer peut être plus asynchrone, vous pouvez utiliser davantage une approche basée sur la messagerie.

Par exemple, ZooKeeper vous permet d'implémenter à peu près tout ce que vous voulez en plus de primitives très simples mais puissantes. Cette page ( http://hadoop.Apache.org/zookeeper/docs/current/recipes.html ) explique comment construire des constructions de niveau supérieur avec ZooKeeper.

L'inconvénient est que vous avez besoin d'un autre système. Si vous utilisez JGroups par exemple, vous ne le faites pas.

J'espère que cela t'aides

1
Yan Pujante

Selon le style de communication que vous recherchez (latence élevée, beaucoup de données, etc.) et si ce système peut s'étendre au-delà de 2 Java Java, une possibilité pourrait être une système de messagerie utilisant une solution middleware telle que Tibco SmartSockets.

Toute autre information sur votre configuration et vos attentes vous aiderait.

0
tinkertime