How to add source folder to a module programmatically ?


I'm trying to add a source folder programmatically, but it does not work. I'm trying to do the following (with IntelliJ 12.1.4) :

public void addSourceFolder(String relativePath, Module module) {
    ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
    File directory = new File(PathMacroUtil.getModuleDir(module.getModuleFilePath()), relativePath);
    if(!directory.exists()) {
    VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(directory);
    ContentEntry e = getContentRootFor(virtualFile, rootModel);
    e.addSourceFolder(virtualFile.getUrl(), false);

private ContentEntry getContentRootFor(VirtualFile url, ModifiableRootModel rootModel) {
    for (ContentEntry e : rootModel.getContentEntries()) {
      if (isEqualOrAncestor(e.getUrl(), url.getUrl())) return e;
    return null;

I call "addSourceFolder" in in a write action. It correctly creates the folder and it appears in the project tree, but it's not marked as a source folder (folder icon is still brown, not blue).

What am I doing wrong ?

Would be great if someone could give me a piece of advice.

Thanks in advance, best regards,



Really ? No one to answer that ? Come on guys, I really need to do that.

The code above is inspired by what I saw in IntelliJ CE's code, but it really does not work. Please help me, I've been working on it for three entire days and I'm running out of time for my development.




First of all, note that you have full access to the source code of IntelliJ IDEA Community Edition, and you can fully step through all that happens in the core when your code runs, and this can usually give you a clue.

The code looks correct to me. I don't know why you're passing VirtualFile.getUrl() instead of VirtualFile directly to addSourceFolder(), but this shouldn't matter.

Could you please attach the .iml file in the state that is produced after your code runs?


Hi Dmitry,

Thanks for your answer, I of course use a lot the CE code (the snippet I gave you is inspired by "MarkRootAction" and "MavenRootModelAdapter").

I tried to invoke this code from an action and it worked. But what I'm currently trying is to invoke it from the "apply()" method of a "FacetEditorTab".

I looked at the .iml file before and after configuring the facet, the "FacetManager" component is correctly updated, but the "NewModuleRootManager" is left unchanged.

Maybe it's a concurrent modification of the .iml file that causes the issue ?

Thanks, best regards,



I finally figure it out. I invoked my "addSourceFolder()" method in "onFacetInitialized()" instead of "apply()" and it now works fine.





Please sign in to leave a comment.