Git Product home page Git Product logo

Comments (7)

decebals avatar decebals commented on May 29, 2024

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.

from pf4j-spring.

dtrunk90 avatar dtrunk90 commented on May 29, 2024

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

from pf4j-spring.

dtrunk90 avatar dtrunk90 commented on May 29, 2024

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.

from pf4j-spring.

dtrunk90 avatar dtrunk90 commented on May 29, 2024

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.

from pf4j-spring.

smitea avatar smitea commented on May 29, 2024

development ?

from pf4j-spring.

smitea avatar smitea commented on May 29, 2024

look at https://pf4j.org/doc/development-mode.html

from pf4j-spring.

satyakatta avatar satyakatta commented on May 29, 2024

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?

from pf4j-spring.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.