Composer doublon de classe (id content-hash)

Hello.

Petite interrogation de ma part concernant la classe init de phpseclib créée et gérée par composer sur ce plugin.
Dans autoload_real.php, elle s’appelle « ComposerAutoloaderInitdfabe774bbbe86d7ea2d09b36c1daed0 ».

Ok, ça semble tout ce qu’il y a de plus unique.
Sauf qu’en regardant de près, « dfabe774bbbe86d7ea2d09b36c1daed0 » est le hash unique (dans composer.lock) à la version du paquet composer de phpseclib. C’est donc ce id unique qui sert à nommer la classe.

Si un autre plugin veux également utiliser phpseclib avec composer et utilise la même version de paquet, on va se retrouver avec 2 fois la même classe instanciée.

Dites-moi si je me trompe, j’ai testé avec un plugin, et c’est systématique l’erreur de classe que je reproduis et en déduis.

En solution :
Dans mon composer.json, j’ai ajouté mon propre « id unique » pour éviter de créer un doublon de nom de classe :

    "config" : {
        "optimize-autoloader": true,
        "autoloader-suffix": "Jailbreak"
    }

Salut,

Comment ajoutes-tu l’autoload dans ton plugin au niveau de ta classe principale ?

Je demande cela, car on est plusieurs à utiliser la lib phpseclib dans des plugins (et souvent dans la même version) et je n’ai pas eu (avant toi :stuck_out_tongue: ) de retour de ce type.

Info qui pourrait t’intéresser par ailleurs, et qui rejoint ce type de sujet justement (de conflit potentiel entre plusieurs plugins sur cette lib), un nouveau plugin en préparation devrait t’intéresser :stuck_out_tongue: (mais il faut encore un tout petit peu de patience)

TiTidom.

if (!class_exists('ComposerAutoloaderInitJailbreak')) {
    require_once dirname(__FILE__) . '/../../vendor/autoload.php';
}

J’ai eu le cas avec une autre lib perso que j’ai importée de la même manière dans deux plugins, et même doublon de classe. Obligé de changer « autoloader-suffix » pour avoir un vrai nom de classe unique.

C’est intéressant, merci pour le retour en tout cas.

Perso, j’importe (en require_once) simplement le vendor/autoload.php et je n’ai (à date) pas eu de soucis.

Est-ce que cela viendrait de la manière de charger la classe ?

Tu as essayé en mettant juste en début de fichier de ton plugin.class.php le require_once ? (comme je fais dans Monitoring) tu as le même message d’erreur ensuite ?

Oui, ça fait planter parce que require_once ne vérifie pas si la classe existe déjà. Juste si le fichier a déjà été importé.

Ce que je m’explique pas, c’est pourquoi on a pas eu de soucis avant :open_mouth:

Je sais que @Mips utilise lui aussi cette lib dans certains de ces plugins, je ne sais pas s’il a déjà eu le cas ?

PS : pour l’instant je cherche juste à comprendre, après s’il faut faire une modif dans mes plugins qui utilisent cette lib, pas de soucis je la ferai :wink:

TiTidom.

Oui, j’ai mis un moment avant de créer ce sujet, parce que je me suis dis que c’était que de mon côté.
Mais 'ai vu que nut_free l’utilisait aussi et que personne n’avait ce plantage.

J’ai 3 plugins qui utilise la lib et la charge de la même façon, utilisé en permanence.
Jamai eu le soucis.
Et c’est (était) pareil avec des class que le core charge(ait) également comme guzzle.

La clé est de ne pas charger des class trop différentes par contre car il n’y en aura qu’une qui sera chargée donc s’il y a un breaking change entre 2 versions, là ca pose problème.

=> as-tu bien limiter la version à php7.4? Je me demande si ton problème n’est pas là

Je ne comprends pas ce que tu veux dire

Ca veut dire quoi « faire planter »?

Je n’ai pas mis de limite, mais tous les tests que j’ai fait étaient sur 7.4.33.

Page blanche jeedom.
dans les logs http.error :

1133|[21-Jun-2024 17:48:01 Europe/Brussels] PHP Fatal error:  Cannot declare class XXX, because the name is already in use in /var/www/html/plugins/XXX/resources/XXX.class.php on line 2

C’est bizarre un fichier class dans resources.

C’était un exemple/test.
C’est pareil dans 3rdparty ou core/class.

Ma question : Comment l’autoload vérifie que la classe n’est pas déjà lancée ? Pour moi, il n’y a pas de vérification.

Hello

Je viens de tomber sur ce problème de double déclaration avec 2 de mes plugins.
Malheureusement dans mon cas c’est une classe avec un singleton static donc je vois pas bien comment m’en sortir sauf a reecrire le code ou dupliquer + renommer la classe ce que je voudrais éviter…
Y a t-il une autre solution que composer pour s’en sortir? Un include avec un namespace différent?

Je ne suis pas familier avec composer, auriez vous un tuto de son utilisation avec jeedom? Est-il lancé par le core à l’install des dépendances ou mettez vous le code généré dans la livraison du plugin?
J’ai fait qques tests d’install avec ma lib en local en m’inspirant de vos fichiers compose.json mais ca ne fonctionne pas il ne la trouve pas. Est-on obligé d’uploader la lib dans github même pour les tests?

@flobul aurais tu un exemple concret à partager?
Merci d’avance

Pour renommer la classe avec un nom « unique » + ta variable « autoloader-suffix ».

Honnêtement, j’ai fait marche arrière pour cloudedge/arenti pour lesquels j’ai une même classe utilisée.
Ma classe à importer contient :

<?php

namespace Flobul\Meari;

class Capabilities
{
...

Et en début de classes eqLogic (arenti/cloudedge):

if (!class_exists('Flobul\\Meari\\Capabilities')) {
    require_once __DIR__ . '/../../3rdparty/Capabilities.php';
}

Merci pour ta réponse @Flobul

Donc tu n’utilises plus composer si j’ai bien cormpris?

if (!class_exists('Flobul\\Meari\\Capabilities')) {
    require_once __DIR__ . '/../../3rdparty/Capabilities.php';
}

J’ai déja essayé ca mais j’ai quand même l’écran blanc.
Comment obtiens-tu un nom unique dans chaque plugin? Il faudrait pouvoir importer la classe en changeant le nom, je ne sais pas si c’est possible.

Salut @Flobul et all

J’ai fini par réussir en ajoutant use as:

if (!class_exists('jeedomtools\MQTTClient'))
      require_once __DIR__ . '/MQTTClient.php';

use jeedomtools\MQTTClient as ble_MQTTClient;

Par contre si je déplace cette classe dans 3rdparty ou vendor ca ne marche plus?? :anguished:
Je n’ai pas réussi à comprendre pourquoi.

J’ai aussi retesté la méthode avec composer. j’ai rigoureusement respecté la structure des autres plugins mais je n’y arrive pas:
Si je lance composer install à la racine il fait une erreur et si je suis dans vendor/lxrootard/jeedom-tools ou que j’utilise l’option -d il me recrée un 2e répertoire vendor que je n’ai pas demandé:

/var/www/html/plugins/blescanner
root@jeedom-dev> composer install -d vendor/lxrootard/jeedom-tools/
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Generating autoload files
root@jeedom-dev> composer install -d tree vendor/
vendor/
└── lxrootard
    └── jeedom-tools
        ├── composer.json
        ├── composer.lock
        ├── src
        │   └── MQTTClient.php
        └── vendor
            ├── autoload.php
            └── composer
                ├── autoload_classmap.php
                ├── autoload_namespaces.php
                ├── autoload_psr4.php
                ├── autoload_real.php
                ├── autoload_static.php
                ├── ClassLoader.php
                ├── installed.json
                ├── installed.php
                ├── InstalledVersions.php
                └── LICENSE

Voici le composer.json à la racine:

{
    "name": "lxrootard/blescanner",
    "description": "blescanner jeedom plugin",
    "license": "GPL",
    "authors": [
        {
            "name": "lxrootard"
        }
    ],
    "require": {
        "lxrootard/jeedom-tools": "~0.1"
    },
    "config": {
        "vendor-dir": "vendor/"
    }
}

et celui de la dépendance:

{
    "name": "lxrootard/jeedom-tools",
    "description": "Jeedom tools",
    "license": "MIT",
    "authors": [
        {
            "name": "lxrootard"
        }
    ],
    "autoload": {
        "psr-0": { "MQTTClient" : "src/" }
    }
}

J’ai raté qqch mais quoi?
Merci :wink:

Bon j’ai fini par trouver mon problème pour la dépendance dans un autre répertoire.

Par contre j’ai laissé tomber composer, il faudrait vraiment que l’un de vous fasse un tuto avec Jeedom…