XML Manipulation
I am trying to create a Maven pom.xml file problematically through the Psi interface. I'm just trying basic modifications, but I can't get anything to write. I am running everything in an
ApplicationManager.getApplication().runWriteAction(() -> { ... });
block.
I try this code:
XmlTag root = pomXmlFile.getRootTag();
XmlTag tag = root.createChildTag("artifactId", "http://maven.apache.org/POM/4.0.0", "test", false);
System.out.println(root);
System.out.println(tag);
root.addSubTag(tag, false);
and as output from the two System.out.println's I get:
XmlTag:project
XmlTag:artifactId
so neither one is null. However, on the 5th line I get:
java.lang.NullPointerException
at com.intellij.psi.impl.source.tree.ChangeUtil.decodeInformation(ChangeUtil.java:87)
at com.intellij.psi.impl.source.tree.ChangeUtil.decodeInformation(ChangeUtil.java:79)
at com.intellij.psi.impl.source.tree.CompositePsiElement.addAfter(CompositePsiElement.java:164)
at com.intellij.psi.impl.source.xml.XmlTagImpl.addSubTag(XmlTagImpl.java:1059)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.lambda$create$0(MavenBuildSystem.java:147)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1009)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.create(MavenBuildSystem.java:113)
at com.demonwav.mcdev.creator.MavenProjectCreator.create(MavenProjectCreator.java:69)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivity(StartupManagerImpl.java:344)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivities(StartupManagerImpl.java:336)
at com.intellij.ide.startup.impl.StartupManagerImpl.runPostStartupActivities(StartupManagerImpl.java:184)
at com.intellij.openapi.project.impl.ProjectManagerImpl$5$2.run(ProjectManagerImpl.java:393)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:345)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:329)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:857)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:658)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:386)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
So I try something else instead. I built the interface tree described here http://www.jetbrains.org/intellij/sdk/docs/reference_guide/frameworks_and_external_apis/xml_dom_api.html and ran this code:
DomManager.getDomManager(project);
MavenProject mavenProject = DomManager.getDomManager(project).getFileElement(pomXmlFile, MavenProject.class, "project").getRootElement();
mavenProject.getArtifactId().setValue("test");
and I get two exceptions on the last line:
com.intellij.util.IncorrectOperationException: Element cannot be added
at com.intellij.psi.impl.source.tree.CompositePsiElement.addInnerBefore(CompositePsiElement.java:322)
at com.intellij.psi.impl.source.tree.CompositePsiElement.add(CompositePsiElement.java:151)
at com.intellij.util.xml.impl.IndexedElementInvocationHandler$1.run(IndexedElementInvocationHandler.java:95)
at com.intellij.util.xml.impl.DomManagerImpl.runChange(DomManagerImpl.java:313)
at com.intellij.util.xml.impl.IndexedElementInvocationHandler.setEmptyXmlTag(IndexedElementInvocationHandler.java:90)
at com.intellij.util.xml.impl.DomInvocationHandler.ensureTagExists(DomInvocationHandler.java:270)
at com.intellij.util.xml.impl.DomInvocationHandler.setValue(DomInvocationHandler.java:149)
at com.intellij.util.xml.impl.SetInvocation.invoke(SetInvocation.java:47)
at com.intellij.util.xml.impl.DomInvocationHandler.invoke(DomInvocationHandler.java:689)
at com.demonwav.mcdev.buildsystem.maven.pom.ArtifactId$$EnhancerByCGLIB$$9385a3fd.setValue(<generated>)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.lambda$create$0(MavenBuildSystem.java:139)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1009)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.create(MavenBuildSystem.java:113)
at com.demonwav.mcdev.creator.MavenProjectCreator.create(MavenProjectCreator.java:69)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivity(StartupManagerImpl.java:344)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivities(StartupManagerImpl.java:336)
at com.intellij.ide.startup.impl.StartupManagerImpl.runPostStartupActivities(StartupManagerImpl.java:184)
at com.intellij.openapi.project.impl.ProjectManagerImpl$5$2.run(ProjectManagerImpl.java:393)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:345)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:329)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:857)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:658)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:386)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'psi' of com/intellij/semantic/SemServiceImpl.setCachedSemElement must not be null
at com.intellij.semantic.SemServiceImpl.setCachedSemElement(SemServiceImpl.java)
at com.intellij.util.xml.impl.DomManagerImpl.cacheHandler(DomManagerImpl.java:159)
at com.intellij.util.xml.impl.DomInvocationHandler.ensureTagExists(DomInvocationHandler.java:276)
at com.intellij.util.xml.impl.DomInvocationHandler.setValue(DomInvocationHandler.java:149)
at com.intellij.util.xml.impl.SetInvocation.invoke(SetInvocation.java:47)
at com.intellij.util.xml.impl.DomInvocationHandler.invoke(DomInvocationHandler.java:689)
at com.demonwav.mcdev.buildsystem.maven.pom.ArtifactId$$EnhancerByCGLIB$$9385a3fd.setValue(<generated>)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.lambda$create$0(MavenBuildSystem.java:139)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1009)
at com.demonwav.mcdev.buildsystem.maven.MavenBuildSystem.create(MavenBuildSystem.java:113)
at com.demonwav.mcdev.creator.MavenProjectCreator.create(MavenProjectCreator.java:69)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivity(StartupManagerImpl.java:344)
at com.intellij.ide.startup.impl.StartupManagerImpl.runActivities(StartupManagerImpl.java:336)
at com.intellij.ide.startup.impl.StartupManagerImpl.runPostStartupActivities(StartupManagerImpl.java:184)
at com.intellij.openapi.project.impl.ProjectManagerImpl$5$2.run(ProjectManagerImpl.java:393)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:345)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:329)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:857)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:658)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:386)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
This is the basis pom.xml file I'm working with:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<build>
<plugins>
<plugin>
<version>3.1</version>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
What am I doing wrong? Thanks.
Please sign in to leave a comment.
Hi Kyle,
One thing you could try is
new WriteCommandAction.Simple(project, psiFile) {@Override
protected void run() throws Throwable {
XmlTag root = pomXmlFile.getRootTag();
XmlTag subTag = rootTag.addSubTag(root.createChildTag("artifactId", "http://maven.apache.org/POM/4.0.0", null, false), false);
}
}.execute();
In here, project variable should be your Project and psiFile is the PsiFile instance of the file you are trying to manipulate (poXmlFile)
When I run that code I just get the
error, whether I wrap it in
ApplicationManager.getApplication().runWriteAction(() -> { ... });or not.
Never mind, I forgot I was creating the file earlier. Here is the whole code block:
and I got this exception:
Okay, after putting that code above in a runWriteAction block with the file creation in that runWriteAction block and the rest in the WriteCommandAction.Simple, it works. I still don't really understand why, but thanks for the help.
In
is the code run asynchronously? If so, is there a way to wait for it to finish? It seems like I'm getting a race condition with this.
I'm not sure, but the WriteCommandAction.Simple runs asynchronously. Best approach for your solution is to create the pom.xml file with all the necessary xml tags within it. When you are creating the file from Text, change the text appropriately, prior to creating the file. (replace variable placeholders with actual values in the text template.)
Thank you, I can't believe I didn't think of that. Changing the order worked perfectly.