diff --git a/modules/packages/maven/metadata.go b/modules/packages/maven/metadata.go
index 42aa250718..a61a62c086 100644
--- a/modules/packages/maven/metadata.go
+++ b/modules/packages/maven/metadata.go
@@ -7,6 +7,7 @@ import (
 	"encoding/xml"
 	"io"
 
+	"code.gitea.io/gitea/modules/util"
 	"code.gitea.io/gitea/modules/validation"
 
 	"golang.org/x/net/html/charset"
@@ -31,18 +32,27 @@ type Dependency struct {
 }
 
 type pomStruct struct {
-	XMLName     xml.Name `xml:"project"`
-	GroupID     string   `xml:"groupId"`
-	ArtifactID  string   `xml:"artifactId"`
-	Version     string   `xml:"version"`
-	Name        string   `xml:"name"`
-	Description string   `xml:"description"`
-	URL         string   `xml:"url"`
-	Licenses    []struct {
+	XMLName xml.Name `xml:"project"`
+
+	Parent struct {
+		GroupID    string `xml:"groupId"`
+		ArtifactID string `xml:"artifactId"`
+		Version    string `xml:"version"`
+	} `xml:"parent"`
+
+	GroupID     string `xml:"groupId"`
+	ArtifactID  string `xml:"artifactId"`
+	Version     string `xml:"version"`
+	Name        string `xml:"name"`
+	Description string `xml:"description"`
+	URL         string `xml:"url"`
+
+	Licenses []struct {
 		Name         string `xml:"name"`
 		URL          string `xml:"url"`
 		Distribution string `xml:"distribution"`
 	} `xml:"licenses>license"`
+
 	Dependencies []struct {
 		GroupID    string `xml:"groupId"`
 		ArtifactID string `xml:"artifactId"`
@@ -81,8 +91,16 @@ func ParsePackageMetaData(r io.Reader) (*Metadata, error) {
 		})
 	}
 
+	pomGroupID := pom.GroupID
+	if pomGroupID == "" {
+		// the current module could inherit parent: https://maven.apache.org/pom.html#Inheritance
+		pomGroupID = pom.Parent.GroupID
+	}
+	if pomGroupID == "" {
+		return nil, util.ErrInvalidArgument
+	}
 	return &Metadata{
-		GroupID:      pom.GroupID,
+		GroupID:      pomGroupID,
 		ArtifactID:   pom.ArtifactID,
 		Name:         pom.Name,
 		Description:  pom.Description,
diff --git a/modules/packages/maven/metadata_test.go b/modules/packages/maven/metadata_test.go
index e675467730..2cff290808 100644
--- a/modules/packages/maven/metadata_test.go
+++ b/modules/packages/maven/metadata_test.go
@@ -7,7 +7,10 @@ import (
 	"strings"
 	"testing"
 
+	"code.gitea.io/gitea/modules/util"
+
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"golang.org/x/text/encoding/charmap"
 )
 
@@ -86,4 +89,35 @@ func TestParsePackageMetaData(t *testing.T) {
 		assert.NoError(t, err)
 		assert.NotNil(t, m)
 	})
+
+	t.Run("ParentInherit", func(t *testing.T) {
+		pom := `<?xml version="1.0"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.mycompany.app</groupId>
+    <artifactId>my-app</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>submodule1</artifactId>
+</project>
+`
+		m, err := ParsePackageMetaData(strings.NewReader(pom))
+		require.NoError(t, err)
+		require.NotNil(t, m)
+
+		assert.Equal(t, "com.mycompany.app", m.GroupID)
+		assert.Equal(t, "submodule1", m.ArtifactID)
+	})
+
+	t.Run("ParentInherit", func(t *testing.T) {
+		pom := `<?xml version="1.0"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId></artifactId>
+</project>
+`
+		_, err := ParsePackageMetaData(strings.NewReader(pom))
+		require.ErrorIs(t, err, util.ErrInvalidArgument)
+	})
 }
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index 92411ecb4f..b50fbd638e 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -461,6 +461,8 @@ func CommonRoutes() *web.Router {
 			r.Post("/api/charts", reqPackageAccess(perm.AccessModeWrite), helm.UploadPackage)
 		}, reqPackageAccess(perm.AccessModeRead))
 		r.Group("/maven", func() {
+			// FIXME: this path design is not right.
+			// It should be `/.../{groupId}/{artifactId}/{version}`, but not `/.../{groupId}-{artifactId}/{version}`
 			r.Put("/*", reqPackageAccess(perm.AccessModeWrite), maven.UploadPackageFile)
 			r.Get("/*", maven.DownloadPackageFile)
 			r.Head("/*", maven.ProvidePackageFileHeader)