Why cannot I execute dbms_space_admin.drop_empty_segments despite granted?
As stated by @Gary in the comment, here is a scenario where a user is still being unable to use the role granted to it even the user has been altered to active the role by default. The user called JAY is already connected to the database. 

SQL&gt; conn jay@oracdbpdb
Enter password:
Connected.


The SYS user performs the following operations to grant EXECUTE on a package to the user via a role.

SQL&gt; CREATE ROLE developer_role;

Role created.

SQL&gt; GRANT EXECUTE ON sys.dbms_space_admin TO developer_role;

Grant succeeded.

SQL&gt; GRANT developer_roleTO jay;

Grant succeeded.

SQL&gt; ALTER USER jay DEFAULT ROLE ALL;

User altered.


However, the user is unable to execute the PLSQL package/procedure. 

SQL&gt; show user
USER is "JAY"

SQL&gt; EXEC SYS.DBMS_SPACE_ADMIN.DROP_EMPTY_SEGMENTS();
BEGIN SYS.DBMS_SPACE_ADMIN.DROP_EMPTY_SEGMENTS(); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.DBMS_SPACE_ADMIN' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored


If I grant the privilege directly to the user then the user is able to execute the PLSQL package.

This is expected behavior because the ALTER statement sets the default role when the user's session starts. Since the user has not been reconnected it was unable to execute the package. However, the user will be able to use the privilege as soon as we grant the privilege directly to the user.

The solution is that the user either should reconnect to the database or explicitly set the role as shown below.

SQL&gt; set role role_name;

Role set.