kandi background
Explore Kits

Activiti | lightweight workflow | BPM library

 by   Activiti Java Version: 7.2.0 License: Apache-2.0

 by   Activiti Java Version: 7.2.0 License: Apache-2.0

Download this library from

kandi X-RAY | Activiti Summary

Activiti is a Java library typically used in Automation, BPM, Spring Boot, Spring, Docker applications. Activiti has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has medium support. You can download it from GitHub, Maven.
[![Join Us in Gitter](https://badges.gitter.im/Activiti/Activiti7.svg)](https://gitter.im/Activiti/Activiti7?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![CI](https://github.com/Activiti/Activiti/actions/workflows/main.yml/badge.svg)](https://github.com/Activiti/Activiti/actions/workflows/main.yml) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8035801ae94c441981f363fa99824a33)](https://www.codacy.com/gh/Activiti/Activiti?utm_source=github.com&utm_medium=referral&utm_content=Activiti/Activiti&utm_campaign=Badge_Grade) [![ASL 2.0](https://img.shields.io/hexpm/l/plug.svg)](https://github.com/Activiti/Activiti/blob/develop/LICENSE.txt) [![CLA](https://cla-assistant.io/readme/badge/Activiti/Activiti)](https://cla-assistant.io/Activiti/Activiti) [![security status](https://www.meterian.io/badge/gh/Activiti/Activiti/security)](https://www.meterian.io/report/gh/Activiti/Activiti) [![stability status](https://www.meterian.io/badge/gh/Activiti/Activiti/stability)](https://www.meterian.io/report/gh/Activiti/Activiti) [![licensing status](https://www.meterian.io/badge/gh/Activiti/Activiti/licensing)](https://www.meterian.io/report/gh/Activiti/Activiti). Activiti is a light-weight workflow and Business Process Management (BPM) Platform targeted at business people, developers and system admins. Its core is a super-fast and rock-solid BPMN 2 process engine for Java. It’s open-source and distributed under the Apache license. Activiti runs in any Java application, on a server, on a cluster or in the cloud. It integrates perfectly with Spring, it is extremely lightweight and based on simple concepts. If you want to read more about our Repositories structure you can read our [GitBook](https://activiti.gitbooks.io/activiti-7-developers-guide/content/).
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • Activiti has a medium active ecosystem.
  • It has 8513 star(s) with 6709 fork(s). There are 648 watchers for this library.
  • There were 1 major release(s) in the last 6 months.
  • There are 400 open issues and 1595 have been closed. On average issues are closed in 179 days. There are 50 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of Activiti is 7.2.0
Activiti Support
Best in #BPM
Average in #BPM
Activiti Support
Best in #BPM
Average in #BPM

quality kandi Quality

  • Activiti has 0 bugs and 0 code smells.
Activiti Quality
Best in #BPM
Average in #BPM
Activiti Quality
Best in #BPM
Average in #BPM

securitySecurity

  • Activiti has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • Activiti code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
Activiti Security
Best in #BPM
Average in #BPM
Activiti Security
Best in #BPM
Average in #BPM

license License

  • Activiti is licensed under the Apache-2.0 License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
Activiti License
Best in #BPM
Average in #BPM
Activiti License
Best in #BPM
Average in #BPM

buildReuse

  • Activiti releases are available to install and integrate.
  • Deployable package is available in Maven.
  • Build file is available. You can build the component from source.
  • Installation instructions are not available. Examples and code snippets are available.
  • Activiti saves you 249547 person hours of effort in developing the same functionality from scratch.
  • It has 246434 lines of code, 19368 functions and 4185 files.
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
Activiti Reuse
Best in #BPM
Average in #BPM
Activiti Reuse
Best in #BPM
Average in #BPM
Top functions reviewed by kandi - BETA

kandi has reviewed Activiti and discovered the below as its top functions. This is intended to give you an instant insight into Activiti implemented functionality, and help decide if they suit your requirements.

  • Store expressions in a string .
  • Draws an activity .
  • Parse a JSON token .
  • Read edgeDI data .
  • Helper method to create a TimerJobJobEntity for a timer event definition
  • Execute an operation on a resource .
  • Converts the given JSON object to BpmnModel .
  • Create data for a variable event .
  • Deletes the given execution entity .
  • Writes the signals and messages .

Activiti Key Features

Activiti is a light-weight workflow and Business Process Management (BPM) Platform targeted at business people, developers and system admins. Its core is a super-fast and rock-solid BPMN 2 process engine for Java. It's open-source and distributed under the Apache license. Activiti runs in any Java application, on a server, on a cluster or in the cloud. It integrates perfectly with Spring, it is extremely lightweight and based on simple concepts.

Add License header

copy iconCopydownload iconDownload
mvn license:format

Checkstyle

copy iconCopydownload iconDownload
mvn checkstyle:check -DskipCheckstyle=false

Site

copy iconCopydownload iconDownload
mvn clean site site:stage

Error: MainActivity must extend android.app.Activity [Instantiatable]

copy iconCopydownload iconDownload
android {
    lintOptions {
        disable "Instantiatable"
    }
}

fastapi (starlette) RedirectResponse redirect to post instead get method

copy iconCopydownload iconDownload
    # ...
    return RedirectResponse(redirect_url, status_code=303)
from fastapi import FastAPI, APIRouter, Request
from fastapi.responses import RedirectResponse, HTMLResponse


router = APIRouter()

@router.get('/form')
def form():
    return HTMLResponse("""
    <html>
    <form action="/event/create" method="POST">
    <button>Send request</button>
    </form>
    </html>
    """)

@router.post('/create')
async def event_create(
        request: Request
):
    event = {"id": 123}
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url, status_code=303)


@router.get('/{pk}')
async def get_event(
        request: Request,
        pk: int,
):
    return f'<html>oi pk={pk}</html>'

app = FastAPI(title='Test API')

app.include_router(router, prefix="/event")
uvicorn --reload --host 0.0.0.0 --port 3000 example:app
-----------------------
    # ...
    return RedirectResponse(redirect_url, status_code=303)
from fastapi import FastAPI, APIRouter, Request
from fastapi.responses import RedirectResponse, HTMLResponse


router = APIRouter()

@router.get('/form')
def form():
    return HTMLResponse("""
    <html>
    <form action="/event/create" method="POST">
    <button>Send request</button>
    </form>
    </html>
    """)

@router.post('/create')
async def event_create(
        request: Request
):
    event = {"id": 123}
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url, status_code=303)


@router.get('/{pk}')
async def get_event(
        request: Request,
        pk: int,
):
    return f'<html>oi pk={pk}</html>'

app = FastAPI(title='Test API')

app.include_router(router, prefix="/event")
uvicorn --reload --host 0.0.0.0 --port 3000 example:app
-----------------------
    # ...
    return RedirectResponse(redirect_url, status_code=303)
from fastapi import FastAPI, APIRouter, Request
from fastapi.responses import RedirectResponse, HTMLResponse


router = APIRouter()

@router.get('/form')
def form():
    return HTMLResponse("""
    <html>
    <form action="/event/create" method="POST">
    <button>Send request</button>
    </form>
    </html>
    """)

@router.post('/create')
async def event_create(
        request: Request
):
    event = {"id": 123}
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url, status_code=303)


@router.get('/{pk}')
async def get_event(
        request: Request,
        pk: int,
):
    return f'<html>oi pk={pk}</html>'

app = FastAPI(title='Test API')

app.include_router(router, prefix="/event")
uvicorn --reload --host 0.0.0.0 --port 3000 example:app
-----------------------
from fastapi import APIRouter, FastAPI, Request, status
from fastapi.responses import RedirectResponse, HTMLResponse

router = APIRouter()

# Endpoint can be accessed at http://127.0.0.1:8000/event/
@router.get('/', response_class=HTMLResponse)
async def event_create_form(request: Request):
    html_content = """
    <html>
       <body>
          <h1>Create an event</h1>
          <form method="POST" action="/event/create">
             <input type="submit" value="Create Event">
          </form>
       </body>
    </html>
    """
    return HTMLResponse(content=html_content, status_code=200)
    
@router.post('/create')
async def event_create(request: Request):
    event = {"id": 1}
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)    

@router.get('/{pk}')
async def get_event(request: Request, pk: int):
    return {"pk": pk}


app = FastAPI()
app.include_router(router, prefix="/event")

Dynamic key type with other key type in typescript

copy iconCopydownload iconDownload
type RecordDto = {
    organizationId?: string;
    displayName?: string;
    photo?: string | null;
    [key: `${number}_tab`]: { isMove:boolean, tabName: string };
    //    ^^^^^^^^^^^^^^^
};
function isValidTabName(name: string): name is `${number}_tab` {
    return /*...validation logic...*/;
}
function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
    if (! /*...validation logic...*/) {
        throw new Error(`The value "${name}" is not a valid tab key`);
    }
}
function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
    assertIsValidTabName(tabKey);
    dto[tabKey] = {isMove, tabName};
}
-----------------------
type RecordDto = {
    organizationId?: string;
    displayName?: string;
    photo?: string | null;
    [key: `${number}_tab`]: { isMove:boolean, tabName: string };
    //    ^^^^^^^^^^^^^^^
};
function isValidTabName(name: string): name is `${number}_tab` {
    return /*...validation logic...*/;
}
function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
    if (! /*...validation logic...*/) {
        throw new Error(`The value "${name}" is not a valid tab key`);
    }
}
function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
    assertIsValidTabName(tabKey);
    dto[tabKey] = {isMove, tabName};
}
-----------------------
type RecordDto = {
    organizationId?: string;
    displayName?: string;
    photo?: string | null;
    [key: `${number}_tab`]: { isMove:boolean, tabName: string };
    //    ^^^^^^^^^^^^^^^
};
function isValidTabName(name: string): name is `${number}_tab` {
    return /*...validation logic...*/;
}
function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
    if (! /*...validation logic...*/) {
        throw new Error(`The value "${name}" is not a valid tab key`);
    }
}
function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
    assertIsValidTabName(tabKey);
    dto[tabKey] = {isMove, tabName};
}
-----------------------
type RecordDto = {
    organizationId?: string;
    displayName?: string;
    photo?: string | null;
    [key: `${number}_tab`]: { isMove:boolean, tabName: string };
    //    ^^^^^^^^^^^^^^^
};
function isValidTabName(name: string): name is `${number}_tab` {
    return /*...validation logic...*/;
}
function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
    if (! /*...validation logic...*/) {
        throw new Error(`The value "${name}" is not a valid tab key`);
    }
}
function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
    assertIsValidTabName(tabKey);
    dto[tabKey] = {isMove, tabName};
}

Select many-to-many relations and pass it to json objects

copy iconCopydownload iconDownload
SELECT events.id, events.title, creatorlateral.creator, memberslateral.members
FROM events
INNER JOIN LATERAL (
  SELECT user_id, json_build_object('id', accounts.user_id, 'name', accounts.name, 'surname', accounts.surname)
  FROM accounts
) creatorlateral(user_id, creator) ON creatorlateral.user_id = events.creator
NATURAL JOIN LATERAL (
  SELECT events_id AS id, json_agg(json_build_object('id', accounts.user_id, 'name', accounts.name, 'surname', accounts.surname))
  FROM events_user
  INNER JOIN accounts ON accounts.user_id = events_user.users_id
  GROUP BY events_id
) memberslateral(id, members)
-----------------------
SELECT
    events.id, events.title, events.creator, events.content, events.status,
    (json_agg(json_build_object('city', locations.city, 'street', locations.street)) -> 0)AS location,
    (json_agg(json_build_object('id', activities.id, 'name', activities.name)) -> 0) AS activity,
    (json_agg(json_build_object('name', a.name, 'surname', a.surname)) -> 0) AS creator,
    json_agg(json_build_object('id', a.user_id, 'name', a.name, 'surname', a.surname)) members
FROM
    events
INNER JOIN
    locations ON events.location_id=locations.id
INNER JOIN
    activities ON events.activities_id=activities.id
INNER JOIN (
  SELECT events_id AS id, 
          a.user_id,
          a.name,
          a.surname
  FROM events_user e
  INNER JOIN accounts a ON a.user_id = e.users_id
) a ON a.id = events.id
WHERE events.id = :pk 
GROUP BY events.id, events.title, events.creator, events.content, events.status
SELECT
    events.id, events.title, events.creator, events.content, events.status,
    (json_agg(json_build_object('city', locations.city, 'street', locations.street)) -> 0)AS location,
    (json_agg(json_build_object('id', activities.id, 'name', activities.name)) -> 0) AS activity,
    (json_agg(json_build_object('name', a.name, 'surname', a.surname)) -> 0) AS creator,
    case when count(t1.user_id) = 0 then '[]' else json_agg(json_build_object('id', t1.user_id, 'name', t1.name, 'surname', t1.surname)) end  members
FROM
    events
INNER JOIN
    locations ON events.location_id=locations.id
INNER JOIN
    activities ON events.activities_id=activities.id
INNER JOIN 
    accounts a ON  events.creator=a.user_id
LEFT JOIN (
  SELECT events_id AS id, 
          a.user_id,
          a.name,
          a.surname
  FROM events_user e
  INNER JOIN accounts a ON a.user_id = e.users_id
) t1 ON t1.id = events.id
WHERE events.id = :pk 
GROUP BY events.id, events.title, events.creator, events.content, events.status
-----------------------
SELECT
    events.id, events.title, events.creator, events.content, events.status,
    (json_agg(json_build_object('city', locations.city, 'street', locations.street)) -> 0)AS location,
    (json_agg(json_build_object('id', activities.id, 'name', activities.name)) -> 0) AS activity,
    (json_agg(json_build_object('name', a.name, 'surname', a.surname)) -> 0) AS creator,
    json_agg(json_build_object('id', a.user_id, 'name', a.name, 'surname', a.surname)) members
FROM
    events
INNER JOIN
    locations ON events.location_id=locations.id
INNER JOIN
    activities ON events.activities_id=activities.id
INNER JOIN (
  SELECT events_id AS id, 
          a.user_id,
          a.name,
          a.surname
  FROM events_user e
  INNER JOIN accounts a ON a.user_id = e.users_id
) a ON a.id = events.id
WHERE events.id = :pk 
GROUP BY events.id, events.title, events.creator, events.content, events.status
SELECT
    events.id, events.title, events.creator, events.content, events.status,
    (json_agg(json_build_object('city', locations.city, 'street', locations.street)) -> 0)AS location,
    (json_agg(json_build_object('id', activities.id, 'name', activities.name)) -> 0) AS activity,
    (json_agg(json_build_object('name', a.name, 'surname', a.surname)) -> 0) AS creator,
    case when count(t1.user_id) = 0 then '[]' else json_agg(json_build_object('id', t1.user_id, 'name', t1.name, 'surname', t1.surname)) end  members
FROM
    events
INNER JOIN
    locations ON events.location_id=locations.id
INNER JOIN
    activities ON events.activities_id=activities.id
INNER JOIN 
    accounts a ON  events.creator=a.user_id
LEFT JOIN (
  SELECT events_id AS id, 
          a.user_id,
          a.name,
          a.surname
  FROM events_user e
  INNER JOIN accounts a ON a.user_id = e.users_id
) t1 ON t1.id = events.id
WHERE events.id = :pk 
GROUP BY events.id, events.title, events.creator, events.content, events.status

How to manage OAuth flow in mobile application with server

copy iconCopydownload iconDownload
curl --location --request POST 'http://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=confidentialclient' \
--data-urlencode 'client_secret=<CLIENT_SECRET_VALUE>' \
--data-urlencode 'code=<AUTHORIZATION_CODE_VALUE>' \
--data-urlencode 'redirect_uri=http://localhost:8080/callback' \
--data-urlencode 'code_verifier=<CODE_VERIFIER_PKCE>'
curl --location --request POST 'http://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=publiclcient' \
--data-urlencode 'code=<AUTHORIZATION_CODE_VALUE>' \
--data-urlencode 'redirect_uri=http://localhost:8080/callback' \
--data-urlencode 'code_verifier=<CODE_VERIFIER_PKCE>'

-----------------------
curl --location --request POST 'http://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=confidentialclient' \
--data-urlencode 'client_secret=<CLIENT_SECRET_VALUE>' \
--data-urlencode 'code=<AUTHORIZATION_CODE_VALUE>' \
--data-urlencode 'redirect_uri=http://localhost:8080/callback' \
--data-urlencode 'code_verifier=<CODE_VERIFIER_PKCE>'
curl --location --request POST 'http://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=publiclcient' \
--data-urlencode 'code=<AUTHORIZATION_CODE_VALUE>' \
--data-urlencode 'redirect_uri=http://localhost:8080/callback' \
--data-urlencode 'code_verifier=<CODE_VERIFIER_PKCE>'

How to get post categories from an object in array

copy iconCopydownload iconDownload
const arr = [
    {
      "category": 1,
      "content": "For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.",
      "content_preview": null,
      "coverImageSubtitle": null,
      "coverImageTitle": null,
      "created_at": "2021-05-13T18:34:17.260Z",
      "custom_link": null,
      "gallery": [],
      "id": 1,
      "isDeleted": null,
      "locale": "sq",
      "localizations": [],
      "pages": [
        {
          "commitments": null,
          "content_sub_menu": null,
          "created_at": "2021-05-19T21:19:15.101Z",
          "id": 18,
          "isActive": true,
          "locale": "sq",
          "name": "Member Listing",
          "showOnFooterMenu": null,
          "showOnMainMenu": null,
          "slug": "member-listing",
          "template": "member-listing",
          "updated_at": "2021-09-28T09:29:56.383Z",
        },
        {
          "commitments": null,
          "content_sub_menu": null,
          "created_at": "2021-05-19T21:33:28.500Z",
          "id": 22,
          "isActive": true,
          "locale": "sq",
          "name": "Evaluation Process / AL",
          "showOnFooterMenu": null,
          "showOnMainMenu": null,
          "slug": "evaluation-process",
          "template": "join-now",
          "updated_at": "2021-05-19T21:33:29.331Z",
        },
      ],
      "post_categories": [
        {
          "created_at": "2021-05-20T15:54:36.949Z",
          "id": 1,
          "locale": "sq",
          "name": "Lajmet",
          "published_at": "2021-05-20T15:54:45.222Z",
          "updated_at": "2021-05-20T15:54:46.179Z",
        },
        {
          "created_at": "2021-05-20T15:54:36.949Z",
          "id": 2,
          "locale": "sq",
          "name": "Lajmet",
          "published_at": "2021-05-20T15:54:45.222Z",
          "updated_at": "2021-05-20T15:54:46.179Z",
        },
      ],
      "published_at": "2021-05-13T18:34:17.260Z",
      "slider": [
        {
          "fixed": null,
          "id": 6,
          "image": [
            {
              "alternativeText": "",
              "caption": "",
              "created_at": "2021-05-13T18:34:10.259Z",
              "ext": ".svg",
              "formats": null,
              "hash": "feature_image_297dbc6cd8",
              "height": 450,
              "id": 11,
              "mime": "image/svg+xml",
              "name": "feature-image.svg",
              "previewUrl": null,
              "provider": "local",
              "provider_metadata": null,
              "size": 54.94,
              "updated_at": "2021-05-13T18:34:10.522Z",
              "url": "/uploads/feature_image_297dbc6cd8.svg",
              "width": 600,
            },
          ],
          "parallax": null,
        },
      ],
      "sort": null,
      "subTitle": null,
      "thumbnail": null,
      "title": "Our Vision, Mission and Guiding Principles",
      "updated_at": "2021-06-22T09:27:39.155Z",
    }]

  console.log(arr.filter(el => el.post_categories.length > 0 && el.id === el.post_categories[0]?.id))
  // console.log(arr.map(el => ({...el, post_categories: el.post_categories.filter(post => post.id === el.category)})))
  

How are Android activities handled with Jetpack Compose and Compose Navigation?

copy iconCopydownload iconDownload
@Composable
fun MainScreen(navController: NavController) {
    LaunchedEffect(Unit) {
        println("LaunchedEffect: entered main")
        var i = 0
        // Just an example of coroutines usage
        // don't use this way to track screen disappearance
        // DisposableEffect is better for this
        try {
            while (true) {
                delay(1000)
                println("LaunchedEffect: ${i++} sec passed")
            }
        } catch (cancel: CancellationException) {
            println("LaunchedEffect: job cancelled")
        }
    }
    DisposableEffect(Unit) {
        println("DisposableEffect: entered main")
        onDispose {
            println("DisposableEffect: exited main")
        }
    }
}

Android Listener stop running when app in background

copy iconCopydownload iconDownload
public void startService() {
      Intent serviceIntent = new Intent(this, MyService.class);
      serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");
      System.out.println("Sensoro 1 ");
      startService(serviceIntent);
  }

facing problem in changing status bar color in jetpack compose

copy iconCopydownload iconDownload
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposePlaygroundTheme {
                window?.setStatusBarColor(Color.Red.toArgb())
            }
        }
    }
}

Collecting Flows in ViewModel. Is repeatOnLifeCycle needed?

copy iconCopydownload iconDownload
val someFlow = prefsRepo.readTokenCredentials()
    .map { data -> // doSomething }
    .shareIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), 1)

Community Discussions

Trending Discussions on Activiti
  • Error: MainActivity must extend android.app.Activity [Instantiatable]
  • fastapi (starlette) RedirectResponse redirect to post instead get method
  • Dynamic key type with other key type in typescript
  • Select many-to-many relations and pass it to json objects
  • How to manage OAuth flow in mobile application with server
  • Manifest merger failed : android:exported needs to be explicitly specified for &lt;activity&gt;
  • Activiti 6.0.0 UI app / in-memory H2 database in tomcat9 / java version &quot;9.0.1&quot;
  • How to get post categories from an object in array
  • How are Android activities handled with Jetpack Compose and Compose Navigation?
  • Android Listener stop running when app in background
Trending Discussions on Activiti

QUESTION

Error: MainActivity must extend android.app.Activity [Instantiatable]

Asked 2022-Mar-31 at 02:13

I tried upgrading Android Gradle Plugin from 4.2.2 to 7.0.1 using the upgrade assistant which is available in Android Studio at Tools > AGP Upgrade Assistant. The only change it made was to my project-level build.gradle file:

buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.1' // changed from 4.2.2 to 7.0.1
        // ...
    }
}

However, now when I run ./gradlew assemble assembleAndroidTest I get the following error:

/builds/locuslabs/android-team/locuslabs-android-sdk/app/src/main/AndroidManifest.xml:21: Error: MainActivity must extend android.app.Activity [Instantiatable]
            android:name="com.locuslabs.appsdk.MainActivity"
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Explanation for issues of type "Instantiatable":
   Activities, services, broadcast receivers etc. registered in the manifest
   file (or for custom views, in a layout file) must be "instantiatable" by
   the system, which means that the class must be public, it must have an
   empty public constructor, and if it's an inner class, it must be a static
   inner class.
1 errors, 0 warnings
Lint found fatal errors while assembling a release target.
To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}

My project is multi-module, but I don't suspect that as the problem since it's complaining about the application module, not a library module.

I believe my <activity> tag is well formed in my AndroidManifest.xml for my application module:

        <activity
            android:name="com.locuslabs.appsdk.MainActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustNothing">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Furthermore, I don't think there is anything wrong with extending AppCompatActivity instead of android.app.Activity as I'm doing in my MainActivity.kt:

import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    // ...
}

I'm concerned that Android Gradle Plugin 7.0.1 is not really ready for prime-time because the Android Gradle Plugin documentation still says classpath 'com.android.tools.build:gradle:4.2.0' instead of 7.0.1.

I saw that the Android Gradle Plugin 7.0.1 release notes mentioned some changes to linting but none of those changes seemed relevant to me.

I also skimmed through the Android Gradle Plugin source code to see if I could find the linting stage any identify any changes but it looked like a lot of work to find that code and do that analysis.

I searched for answers but all I could find were these two stackoverflow entries where the error was legitimate and the programmer just needed to change their code to ensure they were referencing an actual Activity:

  1. Android Studio Error: Activity must extend android.app.activity
  2. MainActivity cannot be cast to android.app.Activity

I also tried Android Gradle Plugin 7.0.0 but got the same error. Only Android Gradle Plugin 4.2.2 prevents the error.

Is this a bug in Android Gradle Plugin 7.0.1?

Update: could not disable Instantiatable

I tried to disable the Instantiatable lint error the following ways but none of them prevented the error.

First, I tried adding disable "Instantiatable" to my application-level build.gradle file:

android {
    lintOptions {
        disable "Instantiatable"
    }
}

Second, I tried prepending @SdkSuppress("Instantiatable") to the class:

@SdkSuppress("Instantiatable")
class MainActivity : AppCompatActivity() {
   // ...
}

Similarly, I tried @SuppressLint("Instantiatable") but that didn't work either.

ANSWER

Answered 2021-Aug-24 at 16:35

the Android Gradle Plugin documentation still says classpath 'com.android.tools.build:gradle:4.2.0' instead of 7.0.1.

You need to read further down the page, to this and this. That table is only relevant for pre-7.0.0 versions.

Is this a bug in Android Gradle Plugin 7.0.1?

Quite possibly. Or, perhaps beyond, as the Instantiatable Lint check has a history of problems.

If your scenario does not match one of those three August 2021 bugs, and you are in position to provide a reproducible test case, file a fresh issue! Beyond that, if a clean-and-rebuild is not clearing up your problem, you might need to simply disable the Instantiatable Lint check for the time being by adding the following to all of your build.gradle files at the application or library level (i.e. all except your project-level build.gradle):

android {
    lintOptions {
        disable "Instantiatable"
    }
}

Source https://stackoverflow.com/questions/68899665

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install Activiti

You can download it from GitHub, Maven.
You can use Activiti like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the Activiti component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .

Support

For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Share this Page

share link
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.