I dislike the build tools that exist for Java. So I wrote my own. But there is one feature that it doesn't have yet; auto-import of changes into the IntelliJ project.
I'm having trouble finding information on how to do this. Tutorials on how to write IntelliJ plugins throw tons of useless stuff at me (creating UI for example).
I know this isn't your typical stackoverflow I-have-a-bug question but I'm quite lost and could use a pointer in the right direction.
If you need to know when a certian file was changed and auto-import information from this file you can use VirtualFileManager.addVirtualFileListener().
Or even use fileDocumentManagerListener extension point. Whatever suits your needs more.
So far I've managed to create a simple IntelliJ plugin. The start is fairly simple. IntelliJ has the plugin project skeleton built in. File->new Project is enough there.
From there I've created a class that implements ModuleComponent. The documentation here (https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_components.html) says it will be loaded whenever a module is opened.
To get it to work I had to add this stuff in the plugin.xml:
<module-components>
<component>
<interface-class>packagename.ClassName</interface-class>
<implementation-class>packagename.ClassName</implementation-class>
</component>
</module-components>
The documentation manages to hide this next step but its possible to give the ModuleComponent a constructor like so:
public ClassName(final Module module) {}
This should give me an instance of the Module class to read values from and to modify the way I need.
As it turns out IntelliJ makes it difficult to figure out how to do things. There is no Javadoc for example. People seem to suggest reading the source code. Weird..
A quick look through the methods of Module didn't really help me much. Google let me know that in order to make changes to the Module I could do the following:
ModuleRootManager.getInstance(module).getModifiableModel()
I can call several methods on this model and finally call .commit() when I'm done to persist the changes. The ModifiableRootModel has two methods that look very promissing:
ModifiableRootModel.addModuleOrderEntry()
ModifiableRootModel.addLibraryEntry()
The first takes a Module instance. I'm hoping that if I add the correct Module this will allow me to well, add modules :). I can think of two situations here. First, the module is already loaded in the project, in which case I will need to find it and add it. And second, the module is not loaded yet so I will need to tell IntelliJ to load it and add it to the project.
The second method takes a Library instance. Just new Library() doesn't work, and google isn't very helpful here. From my buildfile I can extract the groupId:artifactId:version:scope value. So I'll need a way to turn those strings into a Library that works.
This is how far I've gotten so far. Current problems are:
I need to find the already loaded modules so I can find the one I'm linking to
I need a way to add a module to the project if it hasn't been loaded yet
I need a way to turn a maven style dependency into a Library object so I can add it to the module
I need a way to list all the existing modules and libraries so I don't end up adding duplicates
Related
I'd like to do some versioning of some Android code.
I pushed the code (only the res and src directories) and now I want to pull it in some other package.
How can I manage that, given that the code in my git repository has it's source in src/com/some/package/ and I want to clone it and get the source in src/some/other/package/?
I'm aware of this question, but I can't see any answer that helps.
What you can do as an alternative to directly managing it with git, is to separate the common code into its own Android Library Project. Then you would be able to add that library to the other two projects, giving you access to the same code base.
This would have you end up with three projects, and three repositories. Two of each for the separate projects, and one of each for the library project.
One thing to be aware of, however, is that if there is specific code for one project inside of the library, it will also affect the other project. Some of this could be handled by subclassing and overriding methods/properties as needed. Another way around this, as suggested by jul, would be to have branches for each project.
A nice benefit of doing it this way is that if you make a bug fix in the library that you found while working on one project, you'll be able to get that in the other for practically free.
I am currently developing a simple plugin that retrieves results from a Jenkins build. I am extending Notifier and using build.getResults() to get the information. However, when I upload my plugin, I can't set it as a post-build action.
When I run my builds, they break on build.getResults() since I am trying to get the results while the build is still running.
What can I do to properly get the build result ?
Best thing is to look at existing plugins which use Notifier extension point (click to expand implementing plugins list).
Check that you have the Descriptor implemenation (inner) class, as well as config.jelly. Also check jenkins.out and jenkins.err logs for any exceptions (such as malformed config.jelly).
Edit: Actually, Notifier subclass of this plugin looks really simple as Notifiers go: https://wiki.jenkins-ci.org/display/JENKINS/The+Continuous+Integration+Game+plugin , see especially its GamePublisher.java and corresponding config.jelly, and it's GameDescriptor.java, which has been made a full outer class (often descriptor is inner class). Also if you want options into Jenkins' Global configuration, you need a global.jelly, but if you don't have such options, that is something you can just leave out (unlike config.jelly, which you must have for Notifier even if it is empty, like here).
As a general note, it can be really annoying when things do not work, and you do not get any error, your stuff simply is just not displayed by Jenkins... If you just want to get things to work for you, using Groovy build step might be easier, but if you want to get things to work for others, then doing a decent full plugin reduces support requests.
Since this sounds so simple, are you sure you need a plugin ? Take a look at using a Groovy Postbuild step instead; they're much easier to write. There are some good usage examples in the link. If you decide you really need a plugin, see if you can extend an existing one rather than writing your own; it's an easier way to understand the ins and outs of Jenkins plugin writing.
When writing code in an Eclipse project, I'm usually quite messy and undisciplined in how I create and organize my classes, at least in the early hacky and experimental stages. In particular, I create more than one class with a main method for testing different ideas that share most of the same classes.
If I come up with something like a useful app, I can export it to a runnable jar so I can share it with friends. But this simply packs up the whole project, which can become several megabytes big if I'm relying on large library such as httpclient.
Also, if I decide to refactor my lump of code into several projects once I work out what works, and I can't remember which source files are used in a particular run configuration, all I can do it copy the main class to a new project and then keep copying missing types till the new project compiles.
Is there a way in Eclipse to determine which classes are actually used in a particular run configuration?
EDIT: Here's an example. Say I'm experimenting with web scraping, and so far I've tried to scrape the search-result pages of both youtube.com and wrzuta.pl. I have a bunch of classes that implement scraping in general, a few that are specific to each of youtube and wrzuta. On top of this I have a basic gui common to both scrapers, but a few wrzuta- and youtube-specific buttons and options.
The WrzutaGuiMain and YoutubeGuiMain classes each contain a main method to configure and show the gui for each respective website. Can Eclipse look at each of these to determine which types are referenced?
Take a look at ProGuard, it is a "java shrinker, optimizer, obfuscator, and preverifier". I think you'll mainly be interested in the first capability for this problem.
Yes it's not technically part of Eclipse, as you requested, but it can be run from an Ant script, which can be pretty easily run in Eclipse.
I create more than one class with a main method for testing different ideas that share most of the same classes.
It's better to be pedantic than lazy, it saves you time when coding :-)
You can have one class with a main method that accepts a command-line argument and calls a certain branch of functionality based on its value.
This has been bugging me for years now, and I thought one of you fine people would know - in Eclipse's .classpath files, what is the combineaccessrules attribute of the classpathentry element actually used for?
I can see in the Java Build Path config dialog that it can be maniuplated, but I can't think of a good use case for it. If I muck about with the settings, or modify the .classpath file manually, it doesn't seem to have any effect.
I'm hoping someone else has put it to good use, and I can steal their ideas. Basically, it's an itch I'm trying to scratch.
With proper use of access rules you can prevent using "internal" and/or "non-api" classes and methods. When you add a class or package as Forbidden or Discouraged the compiler show an error or warning when you use that class or class from the specified package. For a longer introduction of access rules you should read this short article.
For using combine access rules imagine the following situation:
You have 2 projects, A and B.
On the classpath of project A there is a jar file that is exported. The jar contains some "stable api", "unstable api" and "non-api" public classes.
Project B depends on project A.
You do not allow using "non-api" classes in project A so you set some Forbidden access rules on those classes / packages.
In project B you do not allow using "non-api" as well, but you do want to get a warning when using "unstable api". In this case in project B you only have to set the additional Discouraged access rules if you check the Combine rules with the access rules of the exported project entries.
Access rules are handy little things, but dangerous. They exclude a source file from the project compiler but leave the file intact in the filesystem.
The project I work on has a bootstrap class in one of our source folders, but if we include the entire folder the project classpath it won't compile (it's a long story and the build process handles this).
So we use an eclipse access rule to exclude it and it never bothers us during development. This means we can't easily change the code, but it's one of those classes that literally hasn't been touched in years.
Combine Access Rules, judging by the JavaDoc, is a real edge use case. To use it you would have to have:
an access rule in an exported source entry of one project
a link to that project from a parent project
a need to combine the access rules of the sub project with the parent
I really can't say how it would be useful, but I hope that at least answers your "what is it" question :)
although i have never used it myself, a little bit of into can be found here.
whether the access rules of the project's exported entries should be combined with this entry's access rules
the access rules would be something like including "com/tests/**"
I often read about dependency injection and I did research on google and I understand in theory what it can do and how it works, but I'd like to see an actual code base using it (Java/guice would be preferred).
Can anyone point me to an open source project, where I can see, how it's really used? I think browsing the code and seeing the whole setup shows me more than the ususal snippets in the introduction articles you find around the web. Thanks in advance!
The Wave Protocol Server is my favourite example app.
I struggled a bit with this exact issue. It's so abstract and simple I was always worried I was "doing it wrong".
I've had been using it in the main project which has dependencies on other projects because the Guice module which sets the bindings was part of the main project.
I finally realized the libraries should be supplying the Modules themselves. At that point you can depend only on an instance of a Module (not a specific one), and the interfaces that are bound by it.
Taking it one step better, you can use the new ServiceLoader mechanism in Java 6 to automatically locate and install all Guice modules available on the classpath. Then you can swap in dependencies just by changing class path (db-real.jar vs. db-mock.jar).
I understand you're in Java-land, but in the .NET space the are several open-source apps written using an inversion of control container. Check out CodeCampServer, in which the UI module doesn't have a reference to the dependency resolution module. There is an HttpModule that does the work. (an HttpModule is just a external library you can plug in that handles events in ASP.NET, in CodeCampServer the UI project loads this DependencyRegistrarModule at run time, without any compile time reference to it.)
I think dependency injection has a way of disappearing from view if used properly, it will be just a way of initializing/wiring your application -- if it looks more fancy than that you are probably looking at extra features of the framework at hand, and not at the bare-bones dependency injection.
Edit: I'd recommend actually starting to use it instead of trying to find examples, and then come back and post questions here if you can't get stuff to work like you'd think it should :-)