This has been a fun challenge. Learning more about jenkins internals and
low level java.

I'm thinking i'll put in a hosting req soon, as it is working, but I still
have a bunch of things I want to do for quality of life (like make it able
to filter builds inside jobs).

If anyone wants to compile and run it, there's a working query in the
readme file.

--

This is my solution so far for getting all classes, it does seem to work
though a little redundant.

https://github.com/halkeye/graphql-server-plugin/blob/6dc09b660db299d30ab876a69129d9b9663297bf/src/main/java/io/jenkins/plugins/graphql/ClassUtils.java#L78-L144

private static Set<Class<?>> _getAllClasses() {
        if (_getAllClassesCache != null) { return _getAllClassesCache; }
        _getAllClassesCache = new HashSet<>();

        List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
        classLoadersList.add(ClasspathHelper.contextClassLoader());
        classLoadersList.add(ClasspathHelper.staticClassLoader());
        if (Jenkins.getInstanceOrNull() != null) {
            classLoadersList.addAll(

Jenkins.getInstanceOrNull().getPluginManager().getPlugins().stream()
                    .map(i -> i.classLoader).collect(Collectors.toList())
            );
        }

        try {
            final Field f = ClassLoader.class.getDeclaredField("classes");
            boolean oldAccessible = f.isAccessible();
            f.setAccessible(true);
            for (ClassLoader classLoader : classLoadersList) {
                Vector<Class> classes =  (Vector<Class>) f.get(classLoader);
                for (Class clazz : classes) {
                    if
(clazz.getName().toLowerCase().contains("jenkins") ||
clazz.getName().toLowerCase().contains("hudson")) {
                        _getAllClassesCache.add(clazz);
                    }
                }
            }
            f.setAccessible(oldAccessible);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            LOGGER.info("Unable to use classloader, so falling back to
reflections: " + e.getMessage());
        }

        Reflections reflections = new Reflections(new ConfigurationBuilder()
            .setScanners(
                new SubTypesScanner(
                    false /* don't exclude Object.class */
                ),
                new ResourcesScanner()
            )
            .setUrls(
                ClasspathHelper.forClassLoader(
                    classLoadersList.toArray(
                        new ClassLoader[0]
                    )
                )
            )
            .filterInputsBy(
                new FilterBuilder()
                    .includePackage("com.cloudbees")
                    .includePackage("hudson.model")
                    .includePackage("hudson.plugins")
                    .includePackage("io.jenkins")
                    .includePackage("jenkins.plugins")
                    .includePackage("org.jenkins")
                    .includePackage("org.jenkinsci")
                    .includePackage("org.jenkinsci.plugins.workflow.job")
            )
        );

        _getAllClassesCache.addAll(reflections.getSubTypesOf(Object.class));
        LOGGER.info(
            _getAllClassesCache.stream().filter(i ->
i.getName().contains("WorkflowRun")).collect(Collectors.toList()).toString()
        );
        LOGGER.info(
            _getAllClassesCache.stream().filter(i ->
i.getName().contains("CauseAction")).collect(Collectors.toList()).toString()
        );
        return _getAllClassesCache;
    }


On Mon, Jun 3, 2019 at 5:28 PM Jesse Glick <[email protected]> wrote:

> On Mon, Jun 3, 2019 at 6:25 PM 'Gavin Mogan' via Jenkins Developers
> <[email protected]> wrote:
> > For example. FreeStyleProject/AbstractProject has getAllActions()
> exported as Actions, which I've gotten working in graphql, but I lose the
> ability to have per instance exports.
> >
> > Since action is not an extension point, they are not annotated with
> @Extension, so Is there a another way to get this? Even a slow way cause
> i'm just doing it on startup. I've been trying to google for various ways
> to get all the classes that implement an implementation
>
> Not sure I follow. You are asking if there is a way to get all
> possible `Action` subtypes that might be returned from a
> `getAllActions()` method? If so, it is not possible, at least not in
> any supported way. The same would apply to pretty much any abstract
> type in Jenkins—`Cause`, `CauseOfInterruption`, ad nauseam.
>
> > Can I find all classes that are @Exported?
>
> Without scanning all bytecode in the system? No.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Jenkins Developers" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/jenkinsci-dev/RklYADD2uKc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jenkinsci-dev/CANfRfr38aBtCmGi%3Dhg%2BYK5J7AOADKuLQq%3DwWEP_rV8K0bzA1-w%40mail.gmail.com
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jenkinsci-dev/CAG%3D_Dutnp4%2B862XVCLw61jk8cAmS_DetXM-WtNnzwEJc2ni%2BNg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to