# Configure a module with project resources

**URL:** <https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727>\
**Category:** Module Development\
**Created:** [November 17, 2020, 12:55pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727 "2020-11-17T12:55:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [November 17, 2020, 12:55pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/1 "2020-11-17T12:55:26Z")

</div>

Hello!  
I made a scripting function module that needs some improving. This function has some parameters that I would like to erase, and get the information from somewhere else. The plan is to make a new folder in the Designer’s Project Browser which would open a window similar to “Transaction groups” . In this window I would like to drag tags and maybe enter some parameters. Can I get any input in how to do it?  
For now I have read this guide: [https://docs.inductiveautomation.com/display/SE/Working+with+Project+Resources](https://docs.inductiveautomation.com/display/SE/Working+with+Project+Resources)  
and this post:  
[Project Resources](http://forum.inductiveautomation.com/t/project-resources/29310/4)  
but I don’t really know how to make this happen.

Thank you!

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 17, 2020, 6:54pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/2 "2020-11-17T18:54:09Z")

</div>

The SDK example is completely outdated, as the forum post you linked mentioned. The details in the forum post are mostly correct, but don't answer a lot of your questions.

If you want something to work off of, I actually recently did a standalone project resource example - the only (potential) problem being that it's in Kotlin, rather than Java: [GitHub - paul-griffith/markdown-resources: Example of creating a custom project resource type, with editor, in Ignition](https://github.com/paul-griffith/markdown-resources)

Briefly, Kotlin is an alternate language that can compile down to Java bytecode to run on the JVM. Its syntax is _roughly_ similar to Java, but without a lot of boilerplate - so that may be enough of a hint to get you started, but maybe not.

For a start:

> [@mlunapinel](#):
>
> The plan is to make a new folder in the Designer’s Project Browser which would open a window similar to “Transaction groups”

Notice how my DesignerHook registers a ResourceWorkspace implementation:

> <https://github.com/paul-griffith/markdown-resources/blob/master/designer/src/main/kotlin/com/griffithindustries/samples/designer/MarkdownDesignerHook.kt#L16>

That `MarkdownResourceWorkspace`, when constructing its parent class, creates a `ResourceDescriptor`:

> <https://github.com/paul-griffith/markdown-resources/blob/master/designer/src/main/kotlin/com/griffithindustries/samples/designer/MarkdownWorkspace.kt#L12>

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [November 19, 2020, 10:10am UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/3 "2020-11-19T10:10:58Z")

</div>

Thank you so much @paul-griffith, this is really useful. I will look into this thoroughly.

Cheers!

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [November 26, 2020, 11:00am UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/4 "2020-11-26T11:00:53Z")

</div>

Hello again @paul-griffith,

I’m having some trouble understanding this part of the code:

```auto
override fun createWorkspaceHomeTab(): Optional<JComponent> {
        return object : WorkspaceWelcomePanel("Markdown Notes Workspace Title", null, null) {
            override fun createPanels(): List<JComponent> {
                return listOf(
                    ResourceBuilderPanel(context, "markdown note", MarkdownResource.RESOURCE_TYPE.rootPath(), listOf(
                        ResourceBuilderDelegate.build(
                            "markdown note",
                            VectorIcons.get("resource-note"),
                            newMarkdownNote
                        )
                    ), this@MarkdownWorkspace::open),
                    RecentlyModifiedTablePanel(context,
                        MarkdownResource.RESOURCE_TYPE,
                        "markdown notes",
                        this@MarkdownWorkspace::open)
                )
            }
        }.toOptional()
    }

```

I can’t see clearly what panels is the method creating.  
Specially this part:

```auto
this@MarkdownWorkspace::open

```

What would be the Java substitute?

Also, is there any templates available for a panel similar to the Transactions group one? Or any template at all 🙂 I’m having troubles seeing where can I add components with JFrame.add(JComponent)

Thank you again,

Miguel Luna

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 30, 2020, 4:32pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/5 "2020-11-30T16:32:58Z")

</div>

```auto
this@MarkdownWorkspace::open

```

Is just a non-local method reference - you _can_ do method references in Java (8+), but with some slightly different restrictions - the more typical lambda syntax (which the method reference is just syntactic sugar for) would be something like `resourcePath -> this.open(resourcePath)` - you're providing a lambda, that conforms to the `Consumer<ResourcePath>` functional interface, and thus 'accepts' a `ResourcePath` argument. Method references are allowed as sugar, because as long as your interface only defines one method, and that method only defines one argument, there's no ambiguity for the compiler to resolve - so you could _also_ use a Java method reference, eg:  
`PipelineBlockWorkspace.this::openPipeline`

> [@mlunapinel](#):
>
> Also, is there any templates available for a panel similar to the Transactions group one? Or any template at all 🙂 I’m having troubles seeing where can I add components with JFrame.add(JComponent)

There's no examples for sql bridge - it's a one-off workspace that was basically 'ported' over from the original implementation in FactorySQL. Are you just looking for a 'singleton' resource editor? You don't _have_ to extend `TabbedResourceWorkspace` - it's just that that's usually the simplest path and covers most use cases.

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 1, 2020, 4:14pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/6 "2020-12-01T16:14:25Z")

</div>

Thank you for your response,  
Right now I’m trying to make a resource from where I can get different settings for my module, extending TabbedResourceWorkspace. To simplify the process of making the layout, I’m using Netbean’s swing workspace, making something similar to this:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/b/4b9031250f4b6678c1521f49a8dc73042cbee553.png)  
Which results in the following code:

```auto
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(48, 48, 48)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jScrollPaneIrradiance, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
                    .addComponent(jScrollPaneTemperature)
                    .addComponent(jScrollPaneEnergy))
                .addGap(93, 93, 93)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel4)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5)
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)
                    .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(290, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(40, 40, 40)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPaneTemperature, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel2)
                        .addGap(18, 18, 18)
                        .addComponent(jScrollPaneIrradiance, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel3)
                .addGap(18, 18, 18)
                .addComponent(jScrollPaneEnergy, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(60, Short.MAX_VALUE))
        );

        pack();

```

Then, I add that layout to the method init() in MarkdownEditor, using this.setLayout(…). Keep in mind that this is in an extended ResourceEditor class. The problem that I’m finding is, when I try to create a new Resource Editor, I find the following error:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/4/846e637cca49c7734cffdfc0626ae5e0369ea978.png)

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/c/bcb62816c09be8d9b512169785f7e8dbe9bcd92b.png)

If this method of making the layout is wrong, please, let me know! I’ve looked into MigLayout but it seems pretty complicated, at least compared to Netbean’s graphic workspace.  
Thank you so much for your help!  
Miguel Luna

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [December 1, 2020, 4:39pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/7 "2020-12-01T16:39:41Z")

</div>

That layout is fine - or at least, the error message isn’t indicating any problem in the layout. Your `PREditor` class isn’t handling null data coming in properly - most likely because the resource you’re creating is malformed, or has the wrong data keys, or something along those lines. Notice the stack trace going into `ResourceEditor#loadResource`, then `deserialize`. When implementing a `ResourceEditor` for a custom resource type, you need to choose between:

1. Leaving the resource ‘generic’ - your resource object must be Java serializable (implementing the Serializable interface, and a few other limitations) and will be stored as an opaque `data.bin` file - meaning no ‘nice’ diffing between versions for other users.
2. Implement `serialize(T): byte[]`/`deserialize(byte[]): T` - your resource will still be stored in the `data.bin` file, but you can choose to use your own object serialization/deserialization strategy.
3. Go fully custom and implement `serializeResource` and `deserialize(ProjectResource)`, as I did in the [`MarkdownEditor`](https://github.com/paul-griffith/markdown-resources/blob/master/designer/src/main/kotlin/com/griffithindustries/samples/designer/MarkdownEditor.kt#L27) class. That way, you can choose to store your resource file(s) as their own attributes on disk - in the markdown editor, this is just the `note.md` file.

Assuming you’re still working directly off my example, then the most likely issue is that you have a malformed resource present - you should delete your existing `TestResource`, and ensure that the action to create a new note (in the [workspace configuration](https://github.com/paul-griffith/markdown-resources/blob/master/designer/src/main/kotlin/com/griffithindustries/samples/designer/MarkdownWorkspace.kt#L49)) is creating a resource with the appropriate data key - which, I just noticed, my example is _not_ 🤦‍♂️.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 1, 2020, 4:43pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/8 "2020-12-01T16:43:14Z")

</div>

I used mostly `MigLayout("fill")` and `MigLayout("")` for my Ethernet/IP workspace. Easy-peasy.

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 1, 2020, 4:47pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/9 "2020-12-01T16:47:13Z")

</div>

What would be the right data key? I mean, how do I know it’s correct?

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 1, 2020, 4:48pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/10 "2020-12-01T16:48:54Z")

</div>

Hello Phil. Did you find it hard adding JComponents to your layout using MigLayout? Any advices?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [December 1, 2020, 4:49pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/11 "2020-12-01T16:49:33Z")

</div>

The [example](https://github.com/paul-griffith/markdown-resources/blob/master/designer/src/main/kotlin/com/griffithindustries/samples/designer/MarkdownWorkspace.kt#L26) creates a `Consumer<ProjectResourceBuilder>`, which puts a `readme.md` key into the resource; that should instead be `note.md`/the constant value of [`MarkdownResource.DATA_KEY`](https://github.com/paul-griffith/markdown-resources/blob/master/common/src/main/kotlin/com/griffithindustries/samples/common/MarkdownResource.kt#L8).

And I’ll echo MigLayout - there’s a learning curve, but it can do basically everything you could possibly want for layout, and it’s a whole lot less verbose than what most layout builders spit out. _But_, that’s a secondary concern compared to actually getting this working.

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 1, 2020, 4:50pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/12 "2020-12-01T16:50:07Z")

</div>

Okay, thanks!

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 3, 2020, 1:02pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/13 "2020-12-03T13:02:19Z")

</div>

Hello again @paul-griffith,  
I’m trying to implement these methods in class MarkdownResource:

```auto
 override fun deserialize(resource: ProjectResource): MarkdownResource {
        return resource.getData(MarkdownResource.DATA_KEY)
            ?.takeIf(ByteArray::isNotEmpty)
            ?.toString(Charsets.UTF_8)
            .let { MarkdownResource(it.orEmpty()) }
    }

    override fun serializeResource(builder: ProjectResourceBuilder, resource: MarkdownResource) {
        builder.putData(MarkdownResource.DATA_KEY, resource.note.toByteArray())
    }

```

And this method in class MarkdownWorkspace

```auto
private val newMarkdownNote: (ProjectResourceBuilder) -> Unit = { builder ->
        builder.putData("readme", "Enter a note".toByteArray())
    }

```

Because, as you said, I wasn’t serializing correctly. The problem is that I’m having trouble understanding the kotlin code, and decompiling and compiling to Java doesn’t do the trick for me 😓

I think that after this, I will be able to continue with no problems (hopefully) with my module.

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [December 3, 2020, 4:27pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/14 "2020-12-03T16:27:15Z")

</div>

`deserialize` in Java would be something like:

```auto
    @Override
    protected MarkdownResource deserialize(ProjectResource resource) {
        byte[] data = resource.getData(MarkdownResource.DATA_KEY);
        if (data != null && data.length > 0) {
            return MarkdownResource(String(data, UTF_8));
        } else {
            return MarkdownResource("");
        }
    }

```

`serializeResource` should directly translate to Java code - `toByteArray()` is just an extension method that calls `String.getBytes(UTF-8)`.

`newMarkdownNote` would be a field of type `Consumer<ProjectResourceBuilder>`, something like:

````auto
 private Consumer<ProjectResourceBuilder> newMarkdownNote = (builder) ->
        builder.putData(MarkdownResource.DATA_KEY, "Enter a note".getBytes(UTF_8));```
````

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [December 4, 2020, 8:37am UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/15 "2020-12-04T08:37:02Z")

</div>

Thank you Paul!

---

<div class="post-metadata">

**Author:** ![pdalwalla](https://avatars.discourse-cdn.com/v4/letter/p/54ee81/32.png) [@pdalwalla](https://forum.inductiveautomation.com/u/pdalwalla)\
**Post date:** [January 14, 2021, 8:29pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/16 "2021-01-14T20:29:50Z")

</div>

We are facing the same exact serialization error when we converted the code to Java.  
Were you able to resolve this error; if yes, can you please share what you had to change . We have followed the same exact steps as indicated in all the above discussions. We have also changed the “private Consumer newMarkdownNote = (builder) -\>  
builder.putData( **MarkdownResource.DATA\_KEY** , “Enter a note”.getBytes(UTF\_8));```”. The original source code on github had “readme.md” instead of MarkdownResource.DATA\_KEY.

---

<div class="post-metadata">

**Author:** ![mlunapinel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlunapinel/32/19719_2.png) [@mlunapinel](https://forum.inductiveautomation.com/u/mlunapinel)\
**Post date:** [January 15, 2021, 9:12am UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/17 "2021-01-15T09:12:08Z")

</div>

Hello pdalwalla,

Yes, I got through the error overriding this methods in the class MarkdownEditor (or whatever your class is called):

```auto
@Override
    protected void serializeResource(ProjectResourceBuilder builder, PRResource object){
        builder.putData(PRResource.DATA_KEY,serializeToByte(object));
    }

@Override
    protected PRResource deserialize(ProjectResource resource) {
        byte[] data = resource.getData(PRResource.DATA_KEY);
        if (data != null && data.length > 0) {
            return deserializeToByte(data);
        } else {
            return new PRResource();
        }
    }

    private static byte[] serializeToByte(PRResource obj){
        try{
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream os = new ObjectOutputStream(out);
            os.writeObject(obj);
            return out.toByteArray();

        }catch(Exception e){

        }
        return null;
    }

    private static PRResource deserializeToByte(byte[] data){
        try{
            ByteArrayInputStream in = new ByteArrayInputStream(data);
            ObjectInputStream is = new ObjectInputStream(in);
            return (PRResource) is.readObject();
        }catch(Exception e){

        }
        return null;
    }

```

The only problem I’m running into right now is that I’m not able to save the resource (and load it) properly. If you guys could help me with that 😉

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [January 15, 2021, 3:57pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/18 "2021-01-15T15:57:23Z")

</div>

Are either of you able to post your converted Java code to a public Github instance? I could fork it and try to see what’s going wrong.

---

<div class="post-metadata">

**Author:** ![pdalwalla](https://avatars.discourse-cdn.com/v4/letter/p/54ee81/32.png) [@pdalwalla](https://forum.inductiveautomation.com/u/pdalwalla)\
**Post date:** [January 15, 2021, 5:46pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/19 "2021-01-15T17:46:14Z")

</div>

I think we were able to save the resource with the following code. I received this from our programming team.

Thanks

@Override  
public void addNewResourceActions(ResourceFolderNode arg0, JPopupMenu arg1) {  
arg1.add(new NewResourceAction(this,arg0,newTestNote) {

@Override  
protected String newResourceName() {  
return “note”;  
}

void init(){  
putValue(Action.NAME, “New Note”);  
putValue(Action.SMALL\_ICON, VectorIcons.get(“resource-note”));  
}

});  
}

---

<div class="post-metadata">

**Author:** ![pdalwalla](https://avatars.discourse-cdn.com/v4/letter/p/54ee81/32.png) [@pdalwalla](https://forum.inductiveautomation.com/u/pdalwalla)\
**Post date:** [January 18, 2021, 4:48pm UTC](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727/20 "2021-01-18T16:48:59Z")

</div>

Paul,

We have found some workarounds and still working on some of the code. We will have to separate the code from all the other module code that we have integrated into it. We will try to isolate and upload some working part of the code in a few days. Is github the place to upload?

Thank you

[Next page](https://forum.inductiveautomation.com/t/configure-a-module-with-project-resources/40727.md?page=2)
