Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not possible to create a CRUD repository as ExtensionPoint #26

Open
dtrunk90 opened this issue Jan 3, 2019 · 7 comments
Open

Not possible to create a CRUD repository as ExtensionPoint #26

dtrunk90 opened this issue Jan 3, 2019 · 7 comments

Comments

@dtrunk90
Copy link

dtrunk90 commented Jan 3, 2019

I'm not able to autowire an Extension in an Extension: https://github.com/keering/keering/blob/master/plugins/widgets/chat/src/main/java/com/github/keering/plugins/widgets/chat/service/impl/ChatHistoryServiceImpl.java#L16

You can start the project by running: $ ./gradlew build && cd build && java -jar app-1.0-SNAPSHOT.jar

@decebals
Copy link
Member

decebals commented Jan 3, 2019

I don't understand why you say that ChatHistoryRepository is an extension point.
Put the log of PF4J on trace or debug (see demo) and see the details.

@dtrunk90
Copy link
Author

dtrunk90 commented Jan 3, 2019

Oh well, you're right. I didn't marked ChatHistoryRepository as an extension point. Now I did locally and getting this stacktrace as it is an interface, not a class:

java.lang.InstantiationException: com.github.keering.plugins.widgets.chat.repository.ChatHistoryRepository
        at java.base/java.lang.Class.newInstance(Class.java:547) ~[na:na]
        at org.pf4j.spring.SpringExtensionFactory.createWithoutSpring(SpringExtensionFactory.java:70) [pf4j-spring-0.5.0.jar!/:0.5.0]
        at org.pf4j.spring.SpringExtensionFactory.create(SpringExtensionFactory.java:51) [pf4j-spring-0.5.0.jar!/:0.5.0]
        at org.pf4j.spring.ExtensionsInjector.registerExtension(ExtensionsInjector.java:80) [pf4j-spring-0.5.0.jar!/:0.5.0]
        at org.pf4j.spring.ExtensionsInjector.injectExtensions(ExtensionsInjector.java:64) [pf4j-spring-0.5.0.jar!/:0.5.0]
        at org.pf4j.spring.SpringPluginManager.init(SpringPluginManager.java:66) [pf4j-spring-0.5.0.jar!/:0.5.0]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1737) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:307) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) ~[spring-context-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853) ~[spring-context-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.1.RELEASE.jar!/:2.1.1.RELEASE]
        at com.github.keering.app.Application.main(Application.java:10) ~[classes!/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[app-1.0-SNAPSHOT.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[app-1.0-SNAPSHOT.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[app-1.0-SNAPSHOT.jar:na]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) ~[app-1.0-SNAPSHOT.jar:na]
Caused by: java.lang.NoSuchMethodException: com.github.keering.plugins.widgets.chat.repository.ChatHistoryRepository.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3302) ~[na:na]
        at java.base/java.lang.Class.newInstance(Class.java:532) ~[na:na]
        ... 40 common frames omitted

It's a so called CRUD repository which doesn't need a class:
https://docs.spring.io/spring-data/jpa/docs/1.6.0.RELEASE/reference/html/jpa.repositories.html
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html

@dtrunk90 dtrunk90 changed the title Autowire Extension in Extension leads to NullPointerException Not possible to create a CRUD repository as ExtensionPoint Jan 5, 2019
@dtrunk90
Copy link
Author

dtrunk90 commented Jan 5, 2019

I guess SpringExtensionFactory#createWithoutSpring should check for org.springframework.data.repository.Repository.class.isAssignableFrom(extensionClass) and create a JpaRepositoryFactoryBean instead.

I'll do further research and open up a pull request if it fixes this restriction.

@dtrunk90
Copy link
Author

dtrunk90 commented Jan 6, 2019

I was able to create a bean now with this method:

    protected Object createWithoutSpring(Class<?> extensionClass) {
        try {
            if (isClassAvailable("org.springframework.data.repository.Repository") && Repository.class.isAssignableFrom(extensionClass)) {
                PluginWrapper pluginWrapper = pluginManager.whichPlugin(extensionClass);
                if (pluginWrapper != null) {
                    Plugin plugin = pluginWrapper.getPlugin();
                    if (plugin instanceof SpringPlugin) {
                        JpaRepositoryFactoryBean repositoryFactoryBean = new JpaRepositoryFactoryBean(extensionClass);
                        ApplicationContext pluginContext = ((SpringPlugin) plugin).getApplicationContext();
                        repositoryFactoryBean.setEntityManager(pluginContext.getBean(EntityManager.class));
                        repositoryFactoryBean.setEntityPathResolver(pluginContext.getBeanProvider(EntityPathResolver.class));
                        repositoryFactoryBean.afterPropertiesSet();
                        return repositoryFactoryBean;
                    }
                }
            } else {
                return extensionClass.newInstance();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    private boolean isClassAvailable(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }

But in the end I'm getting this exception:

java.lang.IllegalArgumentException: Not a managed type: class com.github.keering.plugins.widgets.chat.model.jpa.ChatHistory
	at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:552) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:188) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:139) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:123) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:64) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:119) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.pf4j.spring.SpringExtensionFactory.createWithoutSpring(SpringExtensionFactory.java:84) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.SpringExtensionFactory.create(SpringExtensionFactory.java:56) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.ExtensionsInjector.registerExtension(ExtensionsInjector.java:80) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.ExtensionsInjector.injectExtensions(ExtensionsInjector.java:64) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.SpringPluginManager.init(SpringPluginManager.java:66) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]

I also had to add some dependencies in provided scope and update spring version:

diff --git a/pf4j-spring/pom.xml b/pf4j-spring/pom.xml
index b4a6713..748eeb9 100644
--- a/pf4j-spring/pom.xml
+++ b/pf4j-spring/pom.xml
@@ -33,6 +33,27 @@
             <version>${spring.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+            <version>${spring-data.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-jpa</artifactId>
+            <version>${spring-data.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+            <version>${persistence-api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
         <!-- Logs -->
         <dependency>
             <groupId>log4j</groupId>
diff --git a/pom.xml b/pom.xml
index 4ff28ac..3fcf403 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,9 @@
         <java.version>1.7</java.version>
 
         <pf4j.version>2.5.0</pf4j.version>
-        <spring.version>4.0.5.RELEASE</spring.version>
+        <persistence-api.version>1.0.2</persistence-api.version>
+        <spring.version>5.1.0.RELEASE</spring.version>
+        <spring-data.version>2.1.3.RELEASE</spring-data.version>
         <slf4j.version>1.7.5</slf4j.version>
 
         <junit.version>4.12</junit.version>

Maybe it's just not possible. I don't know what to try else.

@smitea
Copy link

smitea commented Feb 14, 2019

development ?

@smitea
Copy link

smitea commented Feb 14, 2019

@satyakatta
Copy link

I was able to create a bean now with this method:

    protected Object createWithoutSpring(Class<?> extensionClass) {
        try {
            if (isClassAvailable("org.springframework.data.repository.Repository") && Repository.class.isAssignableFrom(extensionClass)) {
                PluginWrapper pluginWrapper = pluginManager.whichPlugin(extensionClass);
                if (pluginWrapper != null) {
                    Plugin plugin = pluginWrapper.getPlugin();
                    if (plugin instanceof SpringPlugin) {
                        JpaRepositoryFactoryBean repositoryFactoryBean = new JpaRepositoryFactoryBean(extensionClass);
                        ApplicationContext pluginContext = ((SpringPlugin) plugin).getApplicationContext();
                        repositoryFactoryBean.setEntityManager(pluginContext.getBean(EntityManager.class));
                        repositoryFactoryBean.setEntityPathResolver(pluginContext.getBeanProvider(EntityPathResolver.class));
                        repositoryFactoryBean.afterPropertiesSet();
                        return repositoryFactoryBean;
                    }
                }
            } else {
                return extensionClass.newInstance();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    private boolean isClassAvailable(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }

But in the end I'm getting this exception:

java.lang.IllegalArgumentException: Not a managed type: class com.github.keering.plugins.widgets.chat.model.jpa.ChatHistory
	at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:552) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:188) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:139) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:123) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:64) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:119) ~[spring-data-jpa-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
	at org.pf4j.spring.SpringExtensionFactory.createWithoutSpring(SpringExtensionFactory.java:84) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.SpringExtensionFactory.create(SpringExtensionFactory.java:56) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.ExtensionsInjector.registerExtension(ExtensionsInjector.java:80) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.ExtensionsInjector.injectExtensions(ExtensionsInjector.java:64) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]
	at org.pf4j.spring.SpringPluginManager.init(SpringPluginManager.java:66) [pf4j-spring-0.6.0-SNAPSHOT.jar!/:0.6.0-SNAPSHOT]

I also had to add some dependencies in provided scope and update spring version:

diff --git a/pf4j-spring/pom.xml b/pf4j-spring/pom.xml
index b4a6713..748eeb9 100644
--- a/pf4j-spring/pom.xml
+++ b/pf4j-spring/pom.xml
@@ -33,6 +33,27 @@
             <version>${spring.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+            <version>${spring-data.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-jpa</artifactId>
+            <version>${spring-data.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+            <version>${persistence-api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
         <!-- Logs -->
         <dependency>
             <groupId>log4j</groupId>
diff --git a/pom.xml b/pom.xml
index 4ff28ac..3fcf403 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,9 @@
         <java.version>1.7</java.version>
 
         <pf4j.version>2.5.0</pf4j.version>
-        <spring.version>4.0.5.RELEASE</spring.version>
+        <persistence-api.version>1.0.2</persistence-api.version>
+        <spring.version>5.1.0.RELEASE</spring.version>
+        <spring-data.version>2.1.3.RELEASE</spring-data.version>
         <slf4j.version>1.7.5</slf4j.version>
 
         <junit.version>4.12</junit.version>

Maybe it's just not possible. I don't know what to try else.

Were you able to get the CRUD Repository to work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants